Abstract Classes — Abstract Methods, Template Method Pattern, and Anonymous Classes
In this tutorial, you will learn about Abstract Classes. We cover key concepts, practical examples, and best practices to help you master this topic.
Abstract classes in Java cannot be instantiated and may contain abstract methods that subclasses must implement. Abstract classes sit between concrete classes (fully implemented) and interfaces (fully abstract) — they provide partial implementation and establish a contract for subclasses to fulfill.
What You'll Learn
- Declaring abstract classes and methods
- The Template Method pattern
- Anonymous classes for one-off implementations
- When to use abstract classes vs interfaces
Why It Matters
Abstract classes are the foundation of the Template Method pattern, which is used throughout Java: InputStream, AbstractList, HttpServlet, and AbstractQueuedSynchronizer all use it. Understanding abstract classes helps you design extensible frameworks.
Real-World Use
Spring's AbstractTransactionalJpa4Tests, Java's AbstractCollection, and Swing's AbstractAction all use abstract classes. The Java I/O stream hierarchy (InputStream, OutputStream) is a textbook example of abstract classes.
Abstract Classes
An abstract class is declared with the abstract modifier:
public abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
// Concrete method
public void eat() {
System.out.println(name + " is eating");
}
// Abstract method — no body
public abstract void speak();
}
Key rules:
- Abstract classes cannot be instantiated with
new - They can have constructors (called via
super()from subclasses) - They can have fields, concrete methods, and abstract methods
- If a class has any abstract method, the class must be declared abstract
Subclass Must Implement Abstract Methods
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void speak() {
System.out.println(name + " barks");
}
}
If Dog did not implement speak(), it would need to be declared abstract itself.
The Template Method Pattern
The template method pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses:
public abstract class DataProcessor {
// Template method — defines the algorithm
public final void process() {
loadData();
processData();
saveData();
cleanup();
}
protected abstract void loadData();
protected abstract void processData();
protected abstract void saveData();
// Hook method — optional override
protected void cleanup() {
System.out.println("Cleanup done");
}
}
Subclasses fill in the blanks:
public class CsvProcessor extends DataProcessor {
@Override
protected void loadData() {
System.out.println("Loading CSV file");
}
@Override
protected void processData() {
System.out.println("Processing CSV rows");
}
@Override
protected void saveData() {
System.out.println("Saving CSV results");
}
}
The template method is often final to prevent subclasses from changing the algorithm structure.
Anonymous Classes
Anonymous classes are inline, unnamed classes that implement an interface or extend a class:
// Anonymous class implementing an interface
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Task running");
}
};
// Anonymous class extending a class
Animal pet = new Animal("Pet") {
@Override
public void speak() {
System.out.println("Pet makes a custom sound");
}
};
Anonymous classes are useful for event handlers, callbacks, and one-off implementations:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});
Limitation: Cannot Define Constructors
Anonymous classes cannot have explicit constructors. They use the parent class's constructors or a single instance initializer block:
Animal pet = new Animal("Pet") {
{ // instance initializer
System.out.println("Custom animal created");
}
@Override
public void speak() {
System.out.println("Hello");
}
};
Abstract Classes vs Interfaces
Before Java 8, the choice was clear: abstract classes for shared state and partial implementation, interfaces for pure contracts. Since Java 8 added default and static methods to interfaces, the line has blurred.
| Feature | Abstract Class | Interface |
|---|---|---|
| Instantiation | No | No |
| Fields | Any type | public static final constants only |
| Constructors | Yes | No |
| Methods | Abstract and concrete | Abstract, default, static, private (Java 9+) |
| Multiple inheritance | Single class | Multiple interfaces |
final methods |
Yes | No (default methods can be final in Java 9+) |
| Access modifiers | Any | public (Java 9+ also has private) |
Guidelines
- Prefer interfaces for contracts and polymorphism
- Prefer abstract classes when subclasses share state or partial implementation
- Use abstract classes when you need constructors with parameters
Common Mistakes
- Trying to instantiate an abstract class.
new Animal("x")does not compile. Abstract classes require a concrete subclass. - Forgetting to implement all abstract methods. The compiler catches this, but the error message mentions "declare as abstract" — which is the escape hatch.
- Making the template method non-final. Subclasses can override the template method, breaking the algorithm structure. Mark it
final. - Using abstract classes for pure contracts. If the class has no fields or concrete methods, use an interface instead.
- Overusing anonymous classes. Anonymous classes are verbose. With lambdas (Java 8+), replace anonymous
Runnable/Comparatorwith lambdas.
Practice Questions
1. Can an abstract class have a constructor?
Yes. Abstract classes can have constructors, called via super() from concrete subclasses. The constructor initializes fields defined in the abstract class.
2. What is the template method pattern?
An algorithm skeleton defined in a method, where some steps are abstract and implemented by subclasses. The template method is typically final to preserve the algorithm structure.
3. Can an abstract class implement an interface?
Yes, and it can choose which interface methods to implement and which to leave abstract.
4. What is the difference between an anonymous class and a lambda?
Anonymous classes generate a separate .class file and have access to this (referring to the anonymous instance). Lambdas are more lightweight, compile to invokedynamic, and this refers to the enclosing instance.
5. When would you choose an abstract class over an interface?
When subclasses need to share fields, constructors, or partial implementation. When you need protected access modifiers. When the relationship is hierarchical ("is-a") rather than behavioral ("can-do").
Challenge Question:
Design a GameCharacter abstract class with fields name, health, level. Define a template method attack(GameCharacter target) that calls calculateDamage(), applyDamage(target), and onAttack() (hook). Create Warrior and Mage subclasses with different damage calculations. Add an anonymous class for a custom boss character.
FAQ
Mini Project
Write a program AbstractDemo.java that:
- Defines an abstract
Databaseclass with fieldsurl,username,password - Constructor takes connection parameters
- Defines a template method
connect()that callsloadDriver(),createConnection(),setTimeout(), andlogConnection() loadDriver()andcreateConnection()are abstract;setTimeout()is a hook with default 30 seconds;logConnection()is concrete- Creates
MySQLDatabaseandPostgreSQLDatabasesubclasses - Creates one anonymous subclass for an in-memory H2 database
- Instantiates all three, calls
connect(), and prints the connection flow
What's Next
Abstract classes work well for hierarchical relationships, but Java also supports interface-based contracts. Lesson 16 covers interfaces in depth — including default methods, static methods, private methods (Java 9+), and functional interfaces that enable lambda expressions.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro