Java Programming Abstract Classes Intermediate

Java Abstract Classes & Methods

Learn abstract classes and abstract methods in Java: when to use them, how they differ from interfaces and concrete classes, and the template method pattern—with short, readable examples.

1. Introduction to Abstract Classes

An abstract class cannot be instantiated with new. It is meant to be extended by subclasses. It may contain both concrete methods (with a body) and abstract methods (no body—subclasses must implement them).

  • Declared with the abstract keyword
  • Can have fields, constructors, and implemented methods
  • Forces subclasses to complete unfinished behavior
  • Supports polymorphism: Animal a = new Dog();

Think of an abstract class as a partial blueprint: common parts are built in; specific parts are left for each subclass.

Basic abstract class
abstract class Animal {
    String name;
    Animal(String name) { this.name = name; }
    void eat() { System.out.println(name + " is eating"); }
    abstract void makeSound();  // no body
}
class Dog extends Animal {
    Dog(String name) { super(name); }
    @Override void makeSound() { System.out.println("Woof!"); }
}
// Animal a = new Animal("X");  // ERROR
Animal dog = new Dog("Buddy");
dog.makeSound();

2. Abstract Methods

An abstract method has no implementation. It ends with a semicolon and must be overridden in every concrete subclass.

  • Only allowed inside an abstract class (or interface)
  • Cannot be private, static, or final
  • Subclasses must implement all inherited abstract methods
Abstract method rules
abstract class Shape {
    abstract double getArea();
    abstract void draw();
}
class Circle extends Shape {
    double radius;
    Circle(double r) { radius = r; }
    @Override double getArea() { return Math.PI * radius * radius; }
    @Override void draw() { System.out.println("Drawing circle"); }
}
If a class extends an abstract class but does not implement every abstract method, that subclass must also be declared abstract.

3. Abstract vs Concrete Classes

A concrete class can be instantiated and must implement all abstract methods from its parents. An abstract class acts as a shared base with optional partial implementation.

FeatureAbstract ClassConcrete Class
Keywordabstract classclass
InstantiationNot allowednew MyClass()
Abstract methodsAllowedNot allowed
PurposeBase / templateFull implementation
Employee hierarchy
abstract class Employee {
    protected String name;
    abstract double calculateSalary();
    void display() { System.out.println(name); }
}
class Manager extends Employee {
  @Override double calculateSalary() { return 80000; }
}

4. Template Method Pattern

The template method pattern defines the steps of an algorithm in a base class and lets subclasses fill in specific steps. The template method is often final so the overall flow cannot change.

Template method example
abstract class DataProcessor {
    public final void process() {
        readData();
        transformData();
        saveData();
    }
    abstract void readData();
    void transformData() { /* optional hook */ }
    abstract void saveData();
}
class CSVProcessor extends DataProcessor {
    @Override void readData() { System.out.println("Read CSV"); }
    @Override void saveData() { System.out.println("Save CSV"); }
}

5. Abstract Class vs Interface

Use an interface for a contract (what a class can do). Use an abstract class when related classes share code and state.

FeatureAbstract ClassInterface
InheritanceSingle (extends)Multiple (implements)
FieldsInstance variablesConstants only (traditionally)
ConstructorsYesNo
Best forShared code + IS-ACapabilities / CAN-DO
Interface + abstract class
interface Flyable { void fly(); }
abstract class Bird implements Flyable {
    protected String species;
    Bird(String species) { this.species = species; }
}
class Sparrow extends Bird {
    Sparrow() { super("Sparrow"); }
    @Override public void fly() { System.out.println("Flying"); }
}

6. Real-world Use Cases

Frameworks often use abstract classes: HttpServlet, Thread, JDBC drivers, and game engines define a fixed flow with overridable hooks.

Database connection template

Simplified JDBC-style base
abstract class DatabaseConnection {
    public final void executeQuery(String sql) {
        connect();
        runQuery(sql);
        disconnect();
    }
    abstract void connect();
    abstract void runQuery(String sql);
    abstract void disconnect();
}

Payment processing

Payment processor
abstract class PaymentProcessor {
    public final boolean pay(double amount) {
        if (!validate(amount)) return false;
        return charge(amount);
    }
    boolean validate(double amount) { return amount > 0; }
    abstract boolean charge(double amount);
}

7. Best Practices & Common Mistakes

Do

  • Use abstract classes for true IS-A relationships with shared code
  • Keep the number of abstract methods reasonable
  • Make template methods final when the algorithm must not change
  • Prefer interfaces when you only need a contract

Avoid

  • Trying to instantiate an abstract class
  • Leaving abstract methods unimplemented in concrete subclasses
  • Declaring private abstract or static abstract methods
  • Deep inheritance trees that are hard to maintain
Good vs poor design
// Poor: unrelated abstract methods
abstract class Bad { abstract void fly(); abstract void saveToDb(); }

// Better: focused contract
abstract class Good {
    abstract void performTask();
    protected void log(String msg) { System.out.println(msg); }
}

8. Practice Exercises

  1. Create abstract class Document with load(), save(), and a final process() template method. Implement TextDocument and PDFDocument.
  2. Build abstract Notification with send(); add EmailNotification and SMSNotification.
  3. Design abstract GameCharacter with attack() and shared move(); subclass Warrior and Mage.

9. Summary & Quick Reference

ConceptSyntaxNotes
Abstract classabstract class X { }Cannot use new
Abstract methodabstract void m();No body; must override
Template methodfinal void run() { ... }Fixed algorithm in base class
PolymorphismShape s = new Circle();Reference type = abstract/base

Key takeaways

  • Abstract classes share code and enforce structure for related types.
  • Interfaces define what a class can do; abstract classes define what it is.
  • Template methods give you reusable algorithms with customizable steps.