You have a Shape class with area() method. But "Shape" itself has no area - only Circle and Rectangle do. An abstract class lets you define the method without implementing it, forcing subclasses to provide their own implementation.

Basic abstract class

Define a class that can't be instantiated.

example
BasicAbstract.java
Replay: real traced execution (multi-file project)
// Basic Abstract Class and Method

public class BasicAbstract {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class ===\n");

        // Cannot instantiate abstract class!
        // Animal animal = new Animal();  // ERROR: Animal is abstract

        // Must use concrete subclasses
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.makeSound();
        cat.makeSound();

        System.out.println("\n=== Using Parent Reference ===");

        Animal a1 = new Dog();
        Animal a2 = new Cat();

        a1.makeSound();
        a2.makeSound();

        System.out.println("\n=== Why Use Abstract? ===");
        System.out.println("""
        Abstract classes:

        1. Define a CONTRACT
           - "All animals must make a sound"
           - Subclasses MUST implement makeSound()

        2. Prevent incomplete objects
           - Cannot create a generic "Animal"
           - Must be a specific animal type

        3. Provide common structure
           - Shared fields and methods
           - Specific behavior in subclasses
        """);
    }
}

// Abstract class - cannot instantiate
abstract class Animal {
    String name;

    // Abstract method - no body!
    abstract void makeSound();

    // Notice: no { } curly braces, just semicolon!
}

// Concrete class - MUST implement abstract methods
class Dog extends Animal {
    static String dogSound = "Woof! Woof!";

    @Override
    void makeSound() {
        System.out.println(dogSound);
    }
}

class Cat extends Animal {
    static String catSound = "Meow!";

    @Override
    void makeSound() {
        System.out.println(catSound);
    }
}

// What if we forget to implement?
// class Bird extends Animal {
//     // No makeSound() implementation
//     // ERROR: Bird must implement abstract method makeSound()
// }

// Basic Abstract Class and Method

public class BasicAbstract {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class ===\n");

        // Cannot instantiate abstract class!
        // Animal animal = new Animal();  // ERROR: Animal is abstract

        // Must use concrete subclasses
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.makeSound();
        cat.makeSound();

        System.out.println("\n=== Using Parent Reference ===");

        Animal a1 = new Dog();
        Animal a2 = new Cat();

        a1.makeSound();
        a2.makeSound();

        System.out.println("\n=== Why Use Abstract? ===");
        System.out.println("""
        Abstract classes:

        1. Define a CONTRACT
           - "All animals must make a sound"
           - Subclasses MUST implement makeSound()

        2. Prevent incomplete objects
           - Cannot create a generic "Animal"
           - Must be a specific animal type

        3. Provide common structure
           - Shared fields and methods
           - Specific behavior in subclasses
        """);
    }
}

// Abstract class - cannot instantiate
abstract class Animal {
    String name;

    // Abstract method - no body!
    abstract void makeSound();

    // Notice: no { } curly braces, just semicolon!
}

// Concrete class - MUST implement abstract methods
class Dog extends Animal {
    static String dogSound = "Bark!";

    @Override
    void makeSound() {
        System.out.println(dogSound);
    }
}

class Cat extends Animal {
    static String catSound = "Meow!";

    @Override
    void makeSound() {
        System.out.println(catSound);
    }
}

// What if we forget to implement?
// class Bird extends Animal {
//     // No makeSound() implementation
//     // ERROR: Bird must implement abstract method makeSound()
// }

// Basic Abstract Class and Method

public class BasicAbstract {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class ===\n");

        // Cannot instantiate abstract class!
        // Animal animal = new Animal();  // ERROR: Animal is abstract

        // Must use concrete subclasses
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.makeSound();
        cat.makeSound();

        System.out.println("\n=== Using Parent Reference ===");

        Animal a1 = new Dog();
        Animal a2 = new Cat();

        a1.makeSound();
        a2.makeSound();

        System.out.println("\n=== Why Use Abstract? ===");
        System.out.println("""
        Abstract classes:

        1. Define a CONTRACT
           - "All animals must make a sound"
           - Subclasses MUST implement makeSound()

        2. Prevent incomplete objects
           - Cannot create a generic "Animal"
           - Must be a specific animal type

        3. Provide common structure
           - Shared fields and methods
           - Specific behavior in subclasses
        """);
    }
}

// Abstract class - cannot instantiate
abstract class Animal {
    String name;

    // Abstract method - no body!
    abstract void makeSound();

    // Notice: no { } curly braces, just semicolon!
}

// Concrete class - MUST implement abstract methods
class Dog extends Animal {
    static String dogSound = "Ruff!";

    @Override
    void makeSound() {
        System.out.println(dogSound);
    }
}

class Cat extends Animal {
    static String catSound = "Meow!";

    @Override
    void makeSound() {
        System.out.println(catSound);
    }
}

// What if we forget to implement?
// class Bird extends Animal {
//     // No makeSound() implementation
//     // ERROR: Bird must implement abstract method makeSound()
// }

// Basic Abstract Class and Method

public class BasicAbstract {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class ===\n");

        // Cannot instantiate abstract class!
        // Animal animal = new Animal();  // ERROR: Animal is abstract

        // Must use concrete subclasses
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.makeSound();
        cat.makeSound();

        System.out.println("\n=== Using Parent Reference ===");

        Animal a1 = new Dog();
        Animal a2 = new Cat();

        a1.makeSound();
        a2.makeSound();

        System.out.println("\n=== Why Use Abstract? ===");
        System.out.println("""
        Abstract classes:

        1. Define a CONTRACT
           - "All animals must make a sound"
           - Subclasses MUST implement makeSound()

        2. Prevent incomplete objects
           - Cannot create a generic "Animal"
           - Must be a specific animal type

        3. Provide common structure
           - Shared fields and methods
           - Specific behavior in subclasses
        """);
    }
}

// Abstract class - cannot instantiate
abstract class Animal {
    String name;

    // Abstract method - no body!
    abstract void makeSound();

    // Notice: no { } curly braces, just semicolon!
}

// Concrete class - MUST implement abstract methods
class Dog extends Animal {
    static String dogSound = "Woof! Woof!";

    @Override
    void makeSound() {
        System.out.println(dogSound);
    }
}

class Cat extends Animal {
    static String catSound = "Purr!";

    @Override
    void makeSound() {
        System.out.println(catSound);
    }
}

// What if we forget to implement?
// class Bird extends Animal {
//     // No makeSound() implementation
//     // ERROR: Bird must implement abstract method makeSound()
// }

// Basic Abstract Class and Method

public class BasicAbstract {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class ===\n");

        // Cannot instantiate abstract class!
        // Animal animal = new Animal();  // ERROR: Animal is abstract

        // Must use concrete subclasses
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.makeSound();
        cat.makeSound();

        System.out.println("\n=== Using Parent Reference ===");

        Animal a1 = new Dog();
        Animal a2 = new Cat();

        a1.makeSound();
        a2.makeSound();

        System.out.println("\n=== Why Use Abstract? ===");
        System.out.println("""
        Abstract classes:

        1. Define a CONTRACT
           - "All animals must make a sound"
           - Subclasses MUST implement makeSound()

        2. Prevent incomplete objects
           - Cannot create a generic "Animal"
           - Must be a specific animal type

        3. Provide common structure
           - Shared fields and methods
           - Specific behavior in subclasses
        """);
    }
}

// Abstract class - cannot instantiate
abstract class Animal {
    String name;

    // Abstract method - no body!
    abstract void makeSound();

    // Notice: no { } curly braces, just semicolon!
}

// Concrete class - MUST implement abstract methods
class Dog extends Animal {
    static String dogSound = "Woof! Woof!";

    @Override
    void makeSound() {
        System.out.println(dogSound);
    }
}

class Cat extends Animal {
    static String catSound = "Mrrrow!";

    @Override
    void makeSound() {
        System.out.println(catSound);
    }
}

// What if we forget to implement?
// class Bird extends Animal {
//     // No makeSound() implementation
//     // ERROR: Bird must implement abstract method makeSound()
// }

  1. dog ← ⟨Dog A⟩, cat ← ⟨Cat B⟩

    3public class BasicAbstract {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class ===\n");6        7        // Cannot instantiate abstract class!  //?noinstantiate8        // Animal animal = new Animal();  // ERROR: Animal is abstract9        10        // Must use concrete subclasses  //?usesubclass11        Dog dog→ ⟨Dog A⟩ = new Dog();12        Cat cat→ ⟨Cat B⟩ = new Cat();13        14        dog.makeSound();  //?callabstract15        cat.makeSound();
    output=== Abstract Class ===
  2. @Override void makeSound()

    pass 1 of 2
    14        dog.makeSound();  //?callabstract15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1 = new Dog();  //?parentref20        Animal a2 = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate  //?abstractclass45abstract class Animal {46    String name;47    48    // Abstract method - no body!  //?abstractmethod49    abstract void makeSound();  //?nosemicolon50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods  //?concreteclass55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";  //@dogSound="Bark!", "Ruff!"57    58    @Override59    void makeSound() {  //?dogimpl60        System.out.println(dogSoundWoof! Woof!);61    }
    outputWoof! Woof!
  3. a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩

    pass 1 of 2
    14        dog.makeSound();  //?callabstract15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1→ ⟨Dog C⟩ = new Dog();  //?parentref20        Animal a2→ ⟨Cat D⟩ = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate  //?abstractclass45abstract class Animal {46    String name;47    48    // Abstract method - no body!  //?abstractmethod49    abstract void makeSound();  //?nosemicolon50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods  //?concreteclass55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";  //@dogSound="Bark!", "Ruff!"57    58    @Override59    void makeSound() {  //?dogimpl60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Meow!";  //@catSound="Purr!", "Mrrrow!"66    67    @Override68    void makeSound() {  //?catimpl69        System.out.println(catSoundMeow!);70    }
    outputMeow!
    
    === Using Parent Reference ===
  4. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate  //?abstractclass45abstract class Animal {46    String name;47    48    // Abstract method - no body!  //?abstractmethod49    abstract void makeSound();  //?nosemicolon50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods  //?concreteclass55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";  //@dogSound="Bark!", "Ruff!"57    58    @Override59    void makeSound() {  //?dogimpl60        System.out.println(dogSoundWoof! Woof!);61    }
    outputWoof! Woof!
  5. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate  //?abstractclass45abstract class Animal {46    String name;47    48    // Abstract method - no body!  //?abstractmethod49    abstract void makeSound();  //?nosemicolon50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods  //?concreteclass55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";  //@dogSound="Bark!", "Ruff!"57    58    @Override59    void makeSound() {  //?dogimpl60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Meow!";  //@catSound="Purr!", "Mrrrow!"66    67    @Override68    void makeSound() {  //?catimpl69        System.out.println(catSoundMeow!);70    }
    outputMeow!
    
    === Why Use Abstract? ===
    Abstract classes:
    
    1. Define a CONTRACT
       - "All animals must make a sound"
       - Subclasses MUST implement makeSound()
    
    2. Prevent incomplete objects
       - Cannot create a generic "Animal"
       - Must be a specific animal type
    
    3. Provide common structure
       - Shared fields and methods
       - Specific behavior in subclasses
  1. dog ← ⟨Dog A⟩, cat ← ⟨Cat B⟩

    3public class BasicAbstract {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class ===\n");6        7        // Cannot instantiate abstract class!8        // Animal animal = new Animal();  // ERROR: Animal is abstract9        10        // Must use concrete subclasses11        Dog dog→ ⟨Dog A⟩ = new Dog();12        Cat cat→ ⟨Cat B⟩ = new Cat();13        14        dog.makeSound();15        cat.makeSound();
    output=== Abstract Class ===
  2. @Override void makeSound()

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1 = new Dog();20        Animal a2 = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Bark!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundBark!);61    }
    outputBark!
  3. a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1→ ⟨Dog C⟩ = new Dog();20        Animal a2→ ⟨Cat D⟩ = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Bark!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Meow!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundMeow!);70    }
    outputMeow!
    
    === Using Parent Reference ===
  4. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Bark!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundBark!);61    }
    outputBark!
  5. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Bark!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Meow!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundMeow!);70    }
    outputMeow!
    
    === Why Use Abstract? ===
    Abstract classes:
    
    1. Define a CONTRACT
       - "All animals must make a sound"
       - Subclasses MUST implement makeSound()
    
    2. Prevent incomplete objects
       - Cannot create a generic "Animal"
       - Must be a specific animal type
    
    3. Provide common structure
       - Shared fields and methods
       - Specific behavior in subclasses
  1. dog ← ⟨Dog A⟩, cat ← ⟨Cat B⟩

    3public class BasicAbstract {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class ===\n");6        7        // Cannot instantiate abstract class!8        // Animal animal = new Animal();  // ERROR: Animal is abstract9        10        // Must use concrete subclasses11        Dog dog→ ⟨Dog A⟩ = new Dog();12        Cat cat→ ⟨Cat B⟩ = new Cat();13        14        dog.makeSound();15        cat.makeSound();
    output=== Abstract Class ===
  2. @Override void makeSound()

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1 = new Dog();20        Animal a2 = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Ruff!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundRuff!);61    }
    outputRuff!
  3. a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1→ ⟨Dog C⟩ = new Dog();20        Animal a2→ ⟨Cat D⟩ = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Ruff!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Meow!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundMeow!);70    }
    outputMeow!
    
    === Using Parent Reference ===
  4. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Ruff!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundRuff!);61    }
    outputRuff!
  5. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Ruff!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Meow!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundMeow!);70    }
    outputMeow!
    
    === Why Use Abstract? ===
    Abstract classes:
    
    1. Define a CONTRACT
       - "All animals must make a sound"
       - Subclasses MUST implement makeSound()
    
    2. Prevent incomplete objects
       - Cannot create a generic "Animal"
       - Must be a specific animal type
    
    3. Provide common structure
       - Shared fields and methods
       - Specific behavior in subclasses
  1. dog ← ⟨Dog A⟩, cat ← ⟨Cat B⟩

    3public class BasicAbstract {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class ===\n");6        7        // Cannot instantiate abstract class!8        // Animal animal = new Animal();  // ERROR: Animal is abstract9        10        // Must use concrete subclasses11        Dog dog→ ⟨Dog A⟩ = new Dog();12        Cat cat→ ⟨Cat B⟩ = new Cat();13        14        dog.makeSound();15        cat.makeSound();
    output=== Abstract Class ===
  2. @Override void makeSound()

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1 = new Dog();20        Animal a2 = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundWoof! Woof!);61    }
    outputWoof! Woof!
  3. a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1→ ⟨Dog C⟩ = new Dog();20        Animal a2→ ⟨Cat D⟩ = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Purr!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundPurr!);70    }
    outputPurr!
    
    === Using Parent Reference ===
  4. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundWoof! Woof!);61    }
    outputWoof! Woof!
  5. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Purr!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundPurr!);70    }
    outputPurr!
    
    === Why Use Abstract? ===
    Abstract classes:
    
    1. Define a CONTRACT
       - "All animals must make a sound"
       - Subclasses MUST implement makeSound()
    
    2. Prevent incomplete objects
       - Cannot create a generic "Animal"
       - Must be a specific animal type
    
    3. Provide common structure
       - Shared fields and methods
       - Specific behavior in subclasses
  1. dog ← ⟨Dog A⟩, cat ← ⟨Cat B⟩

    3public class BasicAbstract {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class ===\n");6        7        // Cannot instantiate abstract class!8        // Animal animal = new Animal();  // ERROR: Animal is abstract9        10        // Must use concrete subclasses11        Dog dog→ ⟨Dog A⟩ = new Dog();12        Cat cat→ ⟨Cat B⟩ = new Cat();13        14        dog.makeSound();15        cat.makeSound();
    output=== Abstract Class ===
  2. @Override void makeSound()

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1 = new Dog();20        Animal a2 = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundWoof! Woof!);61    }
    outputWoof! Woof!
  3. a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩

    pass 1 of 2
    14        dog.makeSound();15        cat.makeSound();16        17        System.out.println("\n=== Using Parent Reference ===");18        19        Animal a1→ ⟨Dog C⟩ = new Dog();20        Animal a2→ ⟨Cat D⟩ = new Cat();21        22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Mrrrow!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundMrrrow!);70    }
    outputMrrrow!
    
    === Using Parent Reference ===
  4. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSoundWoof! Woof!);61    }
    outputWoof! Woof!
  5. @Override void makeSound()

    pass 2 of 2
    22        a1.makeSound();23        a2.makeSound();24        25        System.out.println("\n=== Why Use Abstract? ===");26        System.out.println("""27        Abstract classes:28        29        1. Define a CONTRACT30           - "All animals must make a sound"31           - Subclasses MUST implement makeSound()32        33        2. Prevent incomplete objects34           - Cannot create a generic "Animal"35           - Must be a specific animal type36        37        3. Provide common structure38           - Shared fields and methods39           - Specific behavior in subclasses40        """);41    }42}4344// Abstract class - cannot instantiate45abstract class Animal {46    String name;47    48    // Abstract method - no body!49    abstract void makeSound();50    51    // Notice: no { } curly braces, just semicolon!52}5354// Concrete class - MUST implement abstract methods55class Dog extends Animal {56    static String dogSound = "Woof! Woof!";57    58    @Override59    void makeSound() {60        System.out.println(dogSound);61    }62}6364class Cat extends Animal {65    static String catSound = "Mrrrow!";66    67    @Override68    void makeSound() {69        System.out.println(catSoundMrrrow!);70    }
    outputMrrrow!
    
    === Why Use Abstract? ===
    Abstract classes:
    
    1. Define a CONTRACT
       - "All animals must make a sound"
       - Subclasses MUST implement makeSound()
    
    2. Prevent incomplete objects
       - Cannot create a generic "Animal"
       - Must be a specific animal type
    
    3. Provide common structure
       - Shared fields and methods
       - Specific behavior in subclasses

abstract class can't be instantiated. Can have abstract and concrete methods.

abstract class Class that can't be instantiated. May contain abstract methods.

Mix abstract and concrete methods

Provide some implementation, require the rest.

AbstractWithConcrete.java
Replay: real traced execution (multi-file project)
// Mixing Abstract and Concrete Methods

public class AbstractWithConcrete {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class with Concrete Methods ===\n");

        Dog dog = new Dog("Buddy");
        Cat cat = new Cat("Whiskers");

        System.out.println("--- Dog ---");
        dog.introduce();    // Concrete (inherited)
        dog.makeSound();    // Abstract (implemented)
        dog.sleep();        // Concrete (inherited)

        System.out.println("\n--- Cat ---");
        cat.introduce();
        cat.makeSound();
        cat.sleep();

        System.out.println("\n=== Bird Overrides Concrete Method ===");

        Bird bird = new Bird("Tweety");
        bird.introduce();
        bird.makeSound();
        bird.sleep();       // Overridden!

        System.out.println("\n=== Abstract vs Concrete ===");
        System.out.println("""
        Abstract methods:
        - MUST be overridden
        - No default implementation
        - Subclass provides behavior

        Concrete methods:
        - CAN be overridden (optional)
        - Have default implementation
        - Subclass uses or replaces
        """);
    }
}

abstract class Animal {
    protected String name;

    // Constructor in abstract class
    Animal(String name) {
        this.name = name;
    }

    // CONCRETE method - has implementation
    void introduce() {
        System.out.println("Hi, I'm " + name);
    }

    // CONCRETE method - shared behavior
    void sleep() {
        System.out.println(name + " is sleeping... Zzz");
    }

    // ABSTRACT method - subclass must implement
    abstract void makeSound();
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    // MUST implement abstract method
    @Override
    void makeSound() {
        System.out.println(name + " barks: Woof! Woof!");
    }

    // Does NOT override sleep() - uses inherited version
}

class Cat extends Animal {
    Cat(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " meows: Meow!");
    }

    // Also uses inherited sleep()
}

class Bird extends Animal {
    Bird(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " chirps: Tweet! Tweet!");
    }

    // OPTIONAL: Override concrete method
    @Override
    void sleep() {
        System.out.println(name + " perches and sleeps");
    }
}

  1. public static void main(String[] args)

    3public class AbstractWithConcrete {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class with Concrete Methods ===\n");6        7        Dog dog = new Dog("Buddy");8        Cat cat = new Cat("Whiskers");
    output=== Abstract Class with Concrete Methods ===
  2. this.name ← Buddy

    pass 1 of 3
    45// Constructor in abstract class  //?absconstructor46Animal(String nameBuddy) {47    this.name→ Buddy = nameBuddy;48}
    All 3 passes — pass 1 is the card above
    passnamethis.namedogcatbird
    1BuddyBuddy⟨Dog A⟩
    2WhiskersWhiskers⟨Cat B⟩
    3TweetyTweety⟨Bird C⟩
  3. dog ← ⟨Dog A⟩

    7        Dog dog→ ⟨Dog A⟩ = new Dog("Buddy");8        Cat cat = new Cat("Whiskers");9        10        System.out.println("--- Dog ---");11        dog.introduce();    // Concrete (inherited)  //?concrete12        dog.makeSound();    // Abstract (implemented)  //?abstract13        dog.sleep();        // Concrete (inherited)14        15        System.out.println("\n--- Cat ---");16        cat.introduce();17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String nameBuddy) {66        super(name);  //?supercall
  4. cat ← ⟨Cat B⟩

    7        Dog dog = new Dog("Buddy");8        Cat cat→ ⟨Cat B⟩ = new Cat("Whiskers");9        10        System.out.println("--- Dog ---");11        dog.introduce();    // Concrete (inherited)  //?concrete12        dog.makeSound();    // Abstract (implemented)  //?abstract13        dog.sleep();        // Concrete (inherited)14        15        System.out.println("\n--- Cat ---");16        cat.introduce();17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String name) {66        super(name);  //?supercall67    }68    69    // MUST implement abstract method70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof! Woof!");73    }74    75    // Does NOT override sleep() - uses inherited version76}7778class Cat extends Animal {79    Cat(String nameWhiskers) {80        super(name);
    output--- Dog ---
  5. void introduce()

    pass 1 of 3
    10        System.out.println("--- Dog ---");11        dog.introduce();    // Concrete (inherited)  //?concrete12        dog.makeSound();    // Abstract (implemented)  //?abstract13        dog.sleep();        // Concrete (inherited)14        15        System.out.println("\n--- Cat ---");16        cat.introduce();17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + nameBuddy);53    }
    outputHi, I'm Buddy
    All 3 passes — pass 1 is the card above
    passnamebird
    1Buddy
    2Whiskers⟨Bird C⟩
    3Tweety
  6. @Override void makeSound()

    11        dog.introduce();    // Concrete (inherited)  //?concrete12        dog.makeSound();    // Abstract (implemented)  //?abstract13        dog.sleep();        // Concrete (inherited)14        15        System.out.println("\n--- Cat ---");16        cat.introduce();17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String name) {66        super(name);  //?supercall67    }68    69    // MUST implement abstract method70    @Override71    void makeSound() {72        System.out.println(nameBuddy + " barks: Woof! Woof!");73    }
    outputBuddy barks: Woof! Woof!
  7. void sleep()

    pass 1 of 2
    12        dog.makeSound();    // Abstract (implemented)  //?abstract13        dog.sleep();        // Concrete (inherited)14        15        System.out.println("\n--- Cat ---");16        cat.introduce();17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(nameBuddy + " is sleeping... Zzz");58    }
    outputBuddy is sleeping... Zzz
    
    --- Cat ---
  8. @Override void makeSound()

    16        cat.introduce();17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String name) {66        super(name);  //?supercall67    }68    69    // MUST implement abstract method70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof! Woof!");73    }74    75    // Does NOT override sleep() - uses inherited version76}7778class Cat extends Animal {79    Cat(String name) {80        super(name);81    }82    83    @Override84    void makeSound() {85        System.out.println(nameWhiskers + " meows: Meow!");86    }
    outputWhiskers meows: Meow!
  9. void sleep()

    pass 2 of 2
    17        cat.makeSound();18        cat.sleep();19        20        System.out.println("\n=== Bird Overrides Concrete Method ===");21        22        Bird bird = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(nameWhiskers + " is sleeping... Zzz");58    }
    outputWhiskers is sleeping... Zzz
    
    === Bird Overrides Concrete Method ===
  10. bird ← ⟨Bird C⟩

    22        Bird bird→ ⟨Bird C⟩ = new Bird("Tweety");23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String name) {66        super(name);  //?supercall67    }68    69    // MUST implement abstract method70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof! Woof!");73    }74    75    // Does NOT override sleep() - uses inherited version76}7778class Cat extends Animal {79    Cat(String name) {80        super(name);81    }82    83    @Override84    void makeSound() {85        System.out.println(name + " meows: Meow!");86    }87    88    // Also uses inherited sleep()89}9091class Bird extends Animal {92    Bird(String nameTweety) {93        super(name);
  11. @Override void makeSound()

    23        bird.introduce();24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String name) {66        super(name);  //?supercall67    }68    69    // MUST implement abstract method70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof! Woof!");73    }74    75    // Does NOT override sleep() - uses inherited version76}7778class Cat extends Animal {79    Cat(String name) {80        super(name);81    }82    83    @Override84    void makeSound() {85        System.out.println(name + " meows: Meow!");86    }87    88    // Also uses inherited sleep()89}9091class Bird extends Animal {92    Bird(String name) {93        super(name);94    }95    96    @Override97    void makeSound() {98        System.out.println(nameTweety + " chirps: Tweet! Tweet!");99    }
    outputTweety chirps: Tweet! Tweet!
  12. @Override void sleep()

    24        bird.makeSound();25        bird.sleep();       // Overridden!  //?overrideconcrete26        27        System.out.println("\n=== Abstract vs Concrete ===");28        System.out.println("""29        Abstract methods:30        - MUST be overridden31        - No default implementation32        - Subclass provides behavior33        34        Concrete methods:35        - CAN be overridden (optional)36        - Have default implementation37        - Subclass uses or replaces38        """);39    }40}4142abstract class Animal {43    protected String name;44    45    // Constructor in abstract class  //?absconstructor46    Animal(String name) {47        this.name = name;48    }49    50    // CONCRETE method - has implementation  //?concretemethod51    void introduce() {52        System.out.println("Hi, I'm " + name);53    }54    55    // CONCRETE method - shared behavior  //?sharedbehavior56    void sleep() {57        System.out.println(name + " is sleeping... Zzz");58    }59    60    // ABSTRACT method - subclass must implement  //?abstractmethod61    abstract void makeSound();62}6364class Dog extends Animal {65    Dog(String name) {66        super(name);  //?supercall67    }68    69    // MUST implement abstract method70    @Override71    void makeSound() {72        System.out.println(name + " barks: Woof! Woof!");73    }74    75    // Does NOT override sleep() - uses inherited version76}7778class Cat extends Animal {79    Cat(String name) {80        super(name);81    }82    83    @Override84    void makeSound() {85        System.out.println(name + " meows: Meow!");86    }87    88    // Also uses inherited sleep()89}9091class Bird extends Animal {92    Bird(String name) {93        super(name);94    }95    96    @Override97    void makeSound() {98        System.out.println(name + " chirps: Tweet! Tweet!");99    }100    101    // OPTIONAL: Override concrete method  //?overridesleep102    @Override103    void sleep() {104        System.out.println(nameTweety + " perches and sleeps");105    }
    outputTweety perches and sleeps
    
    === Abstract vs Concrete ===
    Abstract methods:
    - MUST be overridden
    - No default implementation
    - Subclass provides behavior
    
    Concrete methods:
    - CAN be overridden (optional)
    - Have default implementation
    - Subclass uses or replaces

Abstract methods have no body. Concrete methods have implementation.

abstract method Method with no body: `abstract void draw();`. Subclass must implement.

Constructors in abstract classes

Abstract classes can have constructors for subclasses.

AbstractConstructor.java
Replay: real traced execution (multi-file project)
// Constructors in Abstract Classes

public class AbstractConstructor {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class Constructors ===\n");

        // Create employees
        Manager manager = new Manager("Alice", 85000, "Engineering");
        Developer developer = new Developer("Bob", 75000, "Java");

        System.out.println("--- Manager ---");
        manager.displayInfo();
        manager.work();

        System.out.println("\n--- Developer ---");
        developer.displayInfo();
        developer.work();

        System.out.println("\n=== Constructor Chain ===");
        System.out.println("""
        When creating Manager("Alice", 85000, "Engineering"):

        1. Manager constructor called
        2. super(name, salary) → Employee constructor
        3. Employee initializes name, salary, id
        4. Manager initializes department

        Even though Employee is abstract,
        its constructor runs!
        """);

        System.out.println("=== Multiple Constructors ===\n");

        // Different constructors
        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");
        Product p2 = new Book("Effective Java");  // Uses default price

        System.out.println("Book 1:");
        p1.displayInfo();

        System.out.println("\nBook 2:");
        p2.displayInfo();
    }
}

// Abstract class with constructor
abstract class Employee {
    protected String name;
    protected double salary;
    protected int employeeId;
    private static int nextId = 1000;

    // Constructor - called by subclasses
    Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
        this.employeeId = nextId++;
        System.out.println("Employee constructor: Creating " + name);
    }

    // Concrete method
    void displayInfo() {
        System.out.println("ID: " + employeeId);
        System.out.println("Name: " + name);
        System.out.println("Salary: $" + salary);
    }

    // Abstract method
    abstract void work();
}

class Manager extends Employee {
    private String department;

    Manager(String name, double salary, String department) {
        super(name, salary);
        this.department = department;
        System.out.println("Manager constructor: Assigned to " + department);
    }

    @Override
    void displayInfo() {
        super.displayInfo();
        System.out.println("Department: " + department);
    }

    @Override
    void work() {
        System.out.println(name + " is managing the " + department + " team");
    }
}

class Developer extends Employee {
    private String language;

    Developer(String name, double salary, String language) {
        super(name, salary);
        this.language = language;
    }

    @Override
    void displayInfo() {
        super.displayInfo();
        System.out.println("Language: " + language);
    }

    @Override
    void work() {
        System.out.println(name + " is coding in " + language);
    }
}

// Abstract class with multiple constructors
abstract class Product {
    protected String name;
    protected double price;

    // Constructor with all params
    Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    // Constructor with default price
    Product(String name) {
        this(name, 0.0);  // Calls other constructor
    }

    void displayInfo() {
        System.out.println("Product: " + name);
        System.out.println("Price: $" + price);
    }

    abstract double calculateTax();
}

class Book extends Product {
    private String author;

    Book(String name, double price, String author) {
        super(name, price);
        this.author = author;
    }

    Book(String name) {
        super(name);  // Uses Product(String) constructor
        this.author = "Unknown";
    }

    @Override
    void displayInfo() {
        super.displayInfo();
        System.out.println("Author: " + author);
    }

    @Override
    double calculateTax() {
        return price * 0.05;  // 5% tax on books
    }
}

  1. public static void main(String[] args)

    3public class AbstractConstructor {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class Constructors ===\n");6        7        // Create employees  //?createemp8        Manager manager = new Manager("Alice", 85000, "Engineering");9        Developer developer = new Developer("Bob", 75000, "Java");
    output=== Abstract Class Constructors ===
  2. this.name ← Alice, this.salary ← 85000.0, nextId ← 1001, this.employeeId ← 1000

    pass 1 of 2
    53// Constructor - called by subclasses  //?empconstructor54Employee(String nameAlice, double salary85000.0) {55    this.name→ Alice = nameAlice;56    this.salary→ 85000.0 = salary85000.0;57    this.employeeId→ 1000 = nextId→ 1001++;  //?autoid58    System.out.println("Employee constructor: Creating " + nameAlice);59}
    outputEmployee constructor: Creating Alice
  3. this.department ← Engineering, manager ← ⟨Manager A⟩

    7        // Create employees  //?createemp8        Manager manager→ ⟨Manager A⟩ = new Manager("Alice", 85000, "Engineering");9        Developer developer = new Developer("Bob", 75000, "Java");10        11        System.out.println("--- Manager ---");12        manager.displayInfo();13        manager.work();14        15        System.out.println("\n--- Developer ---");16        developer.displayInfo();17        developer.work();18        19        System.out.println("\n=== Constructor Chain ===");20        System.out.println("""21        When creating Manager("Alice", 85000, "Engineering"):22        23        1. Manager constructor called24        2. super(name, salary) → Employee constructor25        3. Employee initializes name, salary, id26        4. Manager initializes department27        28        Even though Employee is abstract,29        its constructor runs!30        """);31        32        System.out.println("=== Multiple Constructors ===\n");33        34        // Different constructors  //?multiconst35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String nameAlice, double salary85000.0, String departmentEngineering) {76        super(name, salary);  //?supercall77        this.department→ Engineering = departmentEngineering;78        System.out.println("Manager constructor: Assigned to " + departmentEngineering);79    }
    outputManager constructor: Assigned to Engineering
  4. this.name ← Bob, this.salary ← 75000.0, nextId ← 1002, this.employeeId ← 1001

    pass 2 of 2
    53// Constructor - called by subclasses  //?empconstructor54Employee(String nameBob, double salary75000.0) {55    this.name→ Bob = nameBob;56    this.salary→ 75000.0 = salary75000.0;57    this.employeeId→ 1001 = nextId→ 1002++;  //?autoid58    System.out.println("Employee constructor: Creating " + nameBob);59}
    outputEmployee constructor: Creating Bob
  5. this.language ← Java, developer ← ⟨Developer B⟩

    8        Manager manager = new Manager("Alice", 85000, "Engineering");9        Developer developer→ ⟨Developer B⟩ = new Developer("Bob", 75000, "Java");10        11        System.out.println("--- Manager ---");12        manager.displayInfo();13        manager.work();14        15        System.out.println("\n--- Developer ---");16        developer.displayInfo();17        developer.work();18        19        System.out.println("\n=== Constructor Chain ===");20        System.out.println("""21        When creating Manager("Alice", 85000, "Engineering"):22        23        1. Manager constructor called24        2. super(name, salary) → Employee constructor25        3. Employee initializes name, salary, id26        4. Manager initializes department27        28        Even though Employee is abstract,29        its constructor runs!30        """);31        32        System.out.println("=== Multiple Constructors ===\n");33        34        // Different constructors  //?multiconst35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String nameBob, double salary75000.0, String languageJava) {97        super(name, salary);98        this.language→ Java = languageJava;99    }
    output--- Manager ---
  6. void displayInfo()

    pass 1 of 2
    61// Concrete method62void displayInfo() {63    System.out.println("ID: " + employeeId1000);64    System.out.println("Name: " + nameAlice);65    System.out.println("Salary: $" + salary85000.0);66}
    outputID: 1000
    Name: Alice
    Salary: $85000.0
  7. System.out.println("Department: " + department);

    11        System.out.println("--- Manager ---");12        manager.displayInfo();13        manager.work();14        15        System.out.println("\n--- Developer ---");16        developer.displayInfo();17        developer.work();18        19        System.out.println("\n=== Constructor Chain ===");20        System.out.println("""21        When creating Manager("Alice", 85000, "Engineering"):22        23        1. Manager constructor called24        2. super(name, salary) → Employee constructor25        3. Employee initializes name, salary, id26        4. Manager initializes department27        28        Even though Employee is abstract,29        its constructor runs!30        """);31        32        System.out.println("=== Multiple Constructors ===\n");33        34        // Different constructors  //?multiconst35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + departmentEngineering);85    }
    outputDepartment: Engineering
  8. @Override void work()

    12        manager.displayInfo();13        manager.work();14        15        System.out.println("\n--- Developer ---");16        developer.displayInfo();17        developer.work();18        19        System.out.println("\n=== Constructor Chain ===");20        System.out.println("""21        When creating Manager("Alice", 85000, "Engineering"):22        23        1. Manager constructor called24        2. super(name, salary) → Employee constructor25        3. Employee initializes name, salary, id26        4. Manager initializes department27        28        Even though Employee is abstract,29        its constructor runs!30        """);31        32        System.out.println("=== Multiple Constructors ===\n");33        34        // Different constructors  //?multiconst35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(nameAlice + " is managing the " + departmentEngineering + " team");90    }
    outputAlice is managing the Engineering team
    
    --- Developer ---
  9. void displayInfo()

    pass 2 of 2
    61// Concrete method62void displayInfo() {63    System.out.println("ID: " + employeeId1001);64    System.out.println("Name: " + nameBob);65    System.out.println("Salary: $" + salary75000.0);66}
    outputID: 1001
    Name: Bob
    Salary: $75000.0
  10. System.out.println("Language: " + language);

    15        System.out.println("\n--- Developer ---");16        developer.displayInfo();17        developer.work();18        19        System.out.println("\n=== Constructor Chain ===");20        System.out.println("""21        When creating Manager("Alice", 85000, "Engineering"):22        23        1. Manager constructor called24        2. super(name, salary) → Employee constructor25        3. Employee initializes name, salary, id26        4. Manager initializes department27        28        Even though Employee is abstract,29        its constructor runs!30        """);31        32        System.out.println("=== Multiple Constructors ===\n");33        34        // Different constructors  //?multiconst35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String name, double salary, String language) {97        super(name, salary);98        this.language = language;99    }100    101    @Override102    void displayInfo() {103        super.displayInfo();104        System.out.println("Language: " + languageJava);105    }
    outputLanguage: Java
  11. @Override void work()

    16        developer.displayInfo();17        developer.work();18        19        System.out.println("\n=== Constructor Chain ===");20        System.out.println("""21        When creating Manager("Alice", 85000, "Engineering"):22        23        1. Manager constructor called24        2. super(name, salary) → Employee constructor25        3. Employee initializes name, salary, id26        4. Manager initializes department27        28        Even though Employee is abstract,29        its constructor runs!30        """);31        32        System.out.println("=== Multiple Constructors ===\n");33        34        // Different constructors  //?multiconst35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String name, double salary, String language) {97        super(name, salary);98        this.language = language;99    }100    101    @Override102    void displayInfo() {103        super.displayInfo();104        System.out.println("Language: " + language);105    }106    107    @Override108    void work() {109        System.out.println(nameBob + " is coding in " + languageJava);110    }
    outputBob is coding in Java
    
    === Constructor Chain ===
    When creating Manager("Alice", 85000, "Engineering"):
    
    1. Manager constructor called
    2. super(name, salary) → Employee constructor
    3. Employee initializes name, salary, id
    4. Manager initializes department
    
    Even though Employee is abstract,
    its constructor runs!
    === Multiple Constructors ===
  12. this.name ← Clean Code, this.price ← 44.99

    pass 1 of 2
    118// Constructor with all params119Product(String nameClean Code, double price44.99) {120    this.name→ Clean Code = nameClean Code;121    this.price→ 44.99 = price44.99;122}
  13. this.author ← Robert Martin, p1 ← ⟨Book C⟩

    34        // Different constructors  //?multiconst35        Product p1→ ⟨Book C⟩ = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2 = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String name, double salary, String language) {97        super(name, salary);98        this.language = language;99    }100    101    @Override102    void displayInfo() {103        super.displayInfo();104        System.out.println("Language: " + language);105    }106    107    @Override108    void work() {109        System.out.println(name + " is coding in " + language);110    }111}112113// Abstract class with multiple constructors  //?multipleconst114abstract class Product {115    protected String name;116    protected double price;117    118    // Constructor with all params119    Product(String name, double price) {120        this.name = name;121        this.price = price;122    }123    124    // Constructor with default price  //?defaultprice125    Product(String name) {126        this(name, 0.0);  // Calls other constructor127    }128    129    void displayInfo() {130        System.out.println("Product: " + name);131        System.out.println("Price: $" + price);132    }133    134    abstract double calculateTax();135}136137class Book extends Product {138    private String author;139    140    Book(String nameClean Code, double price44.99, String authorRobert Martin) {141        super(name, price);  //?booksuper142        this.author→ Robert Martin = authorRobert Martin;143    }
  14. this.name ← Effective Java, this.price ← 0.0

    pass 2 of 2
    118// Constructor with all params119Product(String nameEffective Java, double price0.0) {120    this.name→ Effective Java = nameEffective Java;121    this.price→ 0.0 = price0.0;122}
  15. Product(String name)

    124// Constructor with default price  //?defaultprice125Product(String nameEffective Java) {126    this(name, 0.0);  // Calls other constructor
  16. this.author ← Unknown, p2 ← ⟨Book D⟩

    35        Product p1 = new Book("Clean Code", 44.99, "Robert Martin");36        Product p2→ ⟨Book D⟩ = new Book("Effective Java");  // Uses default price37        38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String name, double salary, String language) {97        super(name, salary);98        this.language = language;99    }100    101    @Override102    void displayInfo() {103        super.displayInfo();104        System.out.println("Language: " + language);105    }106    107    @Override108    void work() {109        System.out.println(name + " is coding in " + language);110    }111}112113// Abstract class with multiple constructors  //?multipleconst114abstract class Product {115    protected String name;116    protected double price;117    118    // Constructor with all params119    Product(String name, double price) {120        this.name = name;121        this.price = price;122    }123    124    // Constructor with default price  //?defaultprice125    Product(String name) {126        this(name, 0.0);  // Calls other constructor127    }128    129    void displayInfo() {130        System.out.println("Product: " + name);131        System.out.println("Price: $" + price);132    }133    134    abstract double calculateTax();135}136137class Book extends Product {138    private String author;139    140    Book(String name, double price, String author) {141        super(name, price);  //?booksuper142        this.author = author;143    }144    145    Book(String nameEffective Java) {  //?bookdefault146        super(name);  // Uses Product(String) constructor147        this.author→ Unknown = "Unknown";148    }
    outputBook 1:
  17. void displayInfo()

    pass 1 of 2
    129void displayInfo() {130    System.out.println("Product: " + nameClean Code);131    System.out.println("Price: $" + price44.99);132}
    outputProduct: Clean Code
    Price: $44.99
  18. System.out.println("Author: " + author);

    38        System.out.println("Book 1:");39        p1.displayInfo();40        41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String name, double salary, String language) {97        super(name, salary);98        this.language = language;99    }100    101    @Override102    void displayInfo() {103        super.displayInfo();104        System.out.println("Language: " + language);105    }106    107    @Override108    void work() {109        System.out.println(name + " is coding in " + language);110    }111}112113// Abstract class with multiple constructors  //?multipleconst114abstract class Product {115    protected String name;116    protected double price;117    118    // Constructor with all params119    Product(String name, double price) {120        this.name = name;121        this.price = price;122    }123    124    // Constructor with default price  //?defaultprice125    Product(String name) {126        this(name, 0.0);  // Calls other constructor127    }128    129    void displayInfo() {130        System.out.println("Product: " + name);131        System.out.println("Price: $" + price);132    }133    134    abstract double calculateTax();135}136137class Book extends Product {138    private String author;139    140    Book(String name, double price, String author) {141        super(name, price);  //?booksuper142        this.author = author;143    }144    145    Book(String name) {  //?bookdefault146        super(name);  // Uses Product(String) constructor147        this.author = "Unknown";148    }149    150    @Override151    void displayInfo() {152        super.displayInfo();153        System.out.println("Author: " + authorRobert Martin);154    }
    outputAuthor: Robert Martin
    
    Book 2:
  19. void displayInfo()

    pass 2 of 2
    129void displayInfo() {130    System.out.println("Product: " + nameEffective Java);131    System.out.println("Price: $" + price0.0);132}
    outputProduct: Effective Java
    Price: $0.0
  20. System.out.println("Author: " + author);

    41        System.out.println("\nBook 2:");42        p2.displayInfo();43    }44}4546// Abstract class with constructor  //?absconst47abstract class Employee {48    protected String name;49    protected double salary;50    protected int employeeId;51    private static int nextId = 1000;52    53    // Constructor - called by subclasses  //?empconstructor54    Employee(String name, double salary) {55        this.name = name;56        this.salary = salary;57        this.employeeId = nextId++;  //?autoid58        System.out.println("Employee constructor: Creating " + name);59    }60    61    // Concrete method62    void displayInfo() {63        System.out.println("ID: " + employeeId);64        System.out.println("Name: " + name);65        System.out.println("Salary: $" + salary);66    }67    68    // Abstract method69    abstract void work();  //?abstractwork70}7172class Manager extends Employee {73    private String department;74    75    Manager(String name, double salary, String department) {76        super(name, salary);  //?supercall77        this.department = department;78        System.out.println("Manager constructor: Assigned to " + department);79    }80    81    @Override82    void displayInfo() {83        super.displayInfo();84        System.out.println("Department: " + department);85    }86    87    @Override88    void work() {89        System.out.println(name + " is managing the " + department + " team");90    }91}9293class Developer extends Employee {94    private String language;95    96    Developer(String name, double salary, String language) {97        super(name, salary);98        this.language = language;99    }100    101    @Override102    void displayInfo() {103        super.displayInfo();104        System.out.println("Language: " + language);105    }106    107    @Override108    void work() {109        System.out.println(name + " is coding in " + language);110    }111}112113// Abstract class with multiple constructors  //?multipleconst114abstract class Product {115    protected String name;116    protected double price;117    118    // Constructor with all params119    Product(String name, double price) {120        this.name = name;121        this.price = price;122    }123    124    // Constructor with default price  //?defaultprice125    Product(String name) {126        this(name, 0.0);  // Calls other constructor127    }128    129    void displayInfo() {130        System.out.println("Product: " + name);131        System.out.println("Price: $" + price);132    }133    134    abstract double calculateTax();135}136137class Book extends Product {138    private String author;139    140    Book(String name, double price, String author) {141        super(name, price);  //?booksuper142        this.author = author;143    }144    145    Book(String name) {  //?bookdefault146        super(name);  // Uses Product(String) constructor147        this.author = "Unknown";148    }149    150    @Override151    void displayInfo() {152        super.displayInfo();153        System.out.println("Author: " + authorUnknown);154    }
    outputAuthor: Unknown

Subclass constructor calls super() to initialize parent's fields.

Abstract class hierarchies

Chain abstract classes for layered abstraction.

AbstractChain.java
Replay: real traced execution (multi-file project)
// Abstract Class Hierarchies

public class AbstractChain {
    public static void main(String[] args) {
        System.out.println("=== Abstract Class Hierarchy ===\n");

        // Create concrete vehicles
        Car car = new Car("Toyota", "Camry", 4);
        Motorcycle bike = new Motorcycle("Harley", "Sportster", true);

        System.out.println("--- Car ---");
        car.displayInfo();
        car.start();
        car.accelerate();
        car.brake();

        System.out.println("\n--- Motorcycle ---");
        bike.displayInfo();
        bike.start();
        bike.accelerate();
        bike.brake();

        System.out.println("\n=== Hierarchy Structure ===");
        System.out.println("""

        Vehicle (abstract)           ← Base abstract class
            │
            ├── MotorVehicle (abstract) ← Still abstract!
            │       │
            │       ├── Car (concrete)
            │       └── Motorcycle (concrete)
            │
            └── Bicycle (concrete)    ← Implements all abstract

        """);

        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");

        Bicycle bicycle = new Bicycle("Trek", "FX3");
        bicycle.displayInfo();
        bicycle.start();
        bicycle.accelerate();
        bicycle.brake();
    }
}

// Level 1: Top abstract class
abstract class Vehicle {
    protected String brand;
    protected String model;

    Vehicle(String brand, String model) {
        this.brand = brand;
        this.model = model;
    }

    void displayInfo() {
        System.out.println("Brand: " + brand);
        System.out.println("Model: " + model);
    }

    // Abstract methods - ALL subclasses must implement
    abstract void start();
    abstract void accelerate();
    abstract void brake();
}

// Level 2: Abstract subclass
abstract class MotorVehicle extends Vehicle {
    protected String engineType;

    MotorVehicle(String brand, String model, String engine) {
        super(brand, model);
        this.engineType = engine;
    }

    @Override
    void displayInfo() {
        super.displayInfo();
        System.out.println("Engine: " + engineType);
    }

    // Implement ONE abstract method
    @Override
    void start() {
        System.out.println("Starting " + engineType + " engine...");
    }

    // Leave accelerate() and brake() still abstract!
    // Subclasses must implement them
}

// Level 3: Concrete class
class Car extends MotorVehicle {
    private int numDoors;

    Car(String brand, String model, int doors) {
        super(brand, model, "V6");
        this.numDoors = doors;
    }

    @Override
    void displayInfo() {
        super.displayInfo();
        System.out.println("Doors: " + numDoors);
    }

    // Must implement remaining abstract methods
    @Override
    void accelerate() {
        System.out.println("Car accelerating smoothly...");
    }

    @Override
    void brake() {
        System.out.println("Car braking with ABS...");
    }
}

class Motorcycle extends MotorVehicle {
    private boolean hasSidecar;

    Motorcycle(String brand, String model, boolean sidecar) {
        super(brand, model, "V-Twin");
        this.hasSidecar = sidecar;
    }

    @Override
    void displayInfo() {
        super.displayInfo();
        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));
    }

    @Override
    void accelerate() {
        System.out.println("Motorcycle accelerating fast!");
    }

    @Override
    void brake() {
        System.out.println("Motorcycle braking...");
    }
}

// Alternative: Extends Vehicle directly
class Bicycle extends Vehicle {

    Bicycle(String brand, String model) {
        super(brand, model);
    }

    // Must implement ALL THREE abstract methods
    @Override
    void start() {
        System.out.println("Getting on the bicycle...");
    }

    @Override
    void accelerate() {
        System.out.println("Pedaling faster!");
    }

    @Override
    void brake() {
        System.out.println("Squeezing hand brakes...");
    }
}

  1. public static void main(String[] args)

    3public class AbstractChain {4    public static void main(String[] args) {5        System.out.println("=== Abstract Class Hierarchy ===\n");6        7        // Create concrete vehicles  //?createconcrete8        Car car = new Car("Toyota", "Camry", 4);9        Motorcycle bike = new Motorcycle("Harley", "Sportster", true);
    output=== Abstract Class Hierarchy ===
  2. this.brand ← Toyota, this.model ← Camry

    pass 1 of 3
    52Vehicle(String brandToyota, String modelCamry) {53    this.brand→ Toyota = brandToyota;54    this.model→ Camry = modelCamry;55}
    All 3 passes — pass 1 is the card above
    passbrandmodelenginedoorssidecarthis.brandthis.modelthis.engineTypethis.numDoorscarthis.hasSidecarbikebicycle
    1ToyotaCamryV64ToyotaCamryV64⟨Car A⟩
    2HarleySportsterV-TwintrueHarleySportsterV-Twintrue⟨Motorcycle B⟩
    3TrekFX3TrekFX3⟨Bicycle C⟩
  3. this.engineType ← V6

    pass 1 of 2
    72MotorVehicle(String brandToyota, String modelCamry, String engineV6) {73    super(brand, model);74    this.engineType→ V6 = engineV6;75}
  4. this.numDoors ← 4, car ← ⟨Car A⟩

    7        // Create concrete vehicles  //?createconcrete8        Car car→ ⟨Car A⟩ = new Car("Toyota", "Camry", 4);9        Motorcycle bike = new Motorcycle("Harley", "Sportster", true);10        11        System.out.println("--- Car ---");12        car.displayInfo();13        car.start();14        car.accelerate();15        car.brake();16        17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brandToyota, String modelCamry, int doors4) {98        super(brand, model, "V6");99        this.numDoors→ 4 = doors4;100    }
  5. this.engineType ← V-Twin

    pass 2 of 2
    72MotorVehicle(String brandHarley, String modelSportster, String engineV-Twin) {73    super(brand, model);74    this.engineType→ V-Twin = engineV-Twin;75}
  6. this.hasSidecar ← true, bike ← ⟨Motorcycle B⟩

    8        Car car = new Car("Toyota", "Camry", 4);9        Motorcycle bike→ ⟨Motorcycle B⟩ = new Motorcycle("Harley", "Sportster", true);10        11        System.out.println("--- Car ---");12        car.displayInfo();13        car.start();14        car.accelerate();15        car.brake();16        17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brandHarley, String modelSportster, boolean sidecartrue) {124        super(brand, model, "V-Twin");125        this.hasSidecar→ true = sidecartrue;126    }
    output--- Car ---
  7. void displayInfo()

    pass 1 of 3
    57void displayInfo() {58    System.out.println("Brand: " + brandToyota);59    System.out.println("Model: " + modelCamry);60}
    outputBrand: Toyota
    Model: Camry
    All 3 passes — pass 1 is the card above
    passbrandmodel
    1ToyotaCamry
    2HarleySportster
    3TrekFX3
  8. System.out.println("Engine: " + engineType);

    78void displayInfo() {79    super.displayInfo();80    System.out.println("Engine: " + engineTypeV6);81}
    outputEngine: V6
  9. System.out.println("Doors: " + numDoors);

    11        System.out.println("--- Car ---");12        car.displayInfo();13        car.start();14        car.accelerate();15        car.brake();16        17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors4);106    }
    outputDoors: 4
  10. @Override void start()

    pass 1 of 2
    12        car.displayInfo();13        car.start();14        car.accelerate();15        car.brake();16        17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineTypeV6 + " engine...");87    }
    outputStarting V6 engine...
  11. @Override void accelerate()

    13        car.start();14        car.accelerate();15        car.brake();16        17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }
    outputCar accelerating smoothly...
  12. @Override void brake()

    14        car.accelerate();15        car.brake();16        17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }
    outputCar braking with ABS...
    
    --- Motorcycle ---
  13. System.out.println("Engine: " + engineType);

    78void displayInfo() {79    super.displayInfo();80    System.out.println("Engine: " + engineTypeV-Twin);81}
    outputEngine: V-Twin
  14. System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));

    17        System.out.println("\n--- Motorcycle ---");18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecartrue ? "Yes" : "No"));132    }
    outputSidecar: Yes
  15. @Override void start()

    pass 2 of 2
    18        bike.displayInfo();19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineTypeV-Twin + " engine...");87    }
    outputStarting V-Twin engine...
  16. @Override void accelerate()

    19        bike.start();20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));132    }133    134    @Override135    void accelerate() {136        System.out.println("Motorcycle accelerating fast!");137    }
    outputMotorcycle accelerating fast!
  17. @Override void brake()

    20        bike.accelerate();21        bike.brake();22        23        System.out.println("\n=== Hierarchy Structure ===");24        System.out.println("""25        26        Vehicle (abstract)           ← Base abstract class2728            ├── MotorVehicle (abstract) ← Still abstract!29            │       │30            │       ├── Car (concrete)31            │       └── Motorcycle (concrete)3233            └── Bicycle (concrete)    ← Implements all abstract34        35        """);36        37        System.out.println("=== Bicycle (extends Vehicle directly) ===\n");38        39        Bicycle bicycle = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));132    }133    134    @Override135    void accelerate() {136        System.out.println("Motorcycle accelerating fast!");137    }138    139    @Override140    void brake() {141        System.out.println("Motorcycle braking...");142    }
    outputMotorcycle braking...
    
    === Hierarchy Structure ===
    
    Vehicle (abstract)           ← Base abstract class
        │
        ├── MotorVehicle (abstract) ← Still abstract!
        │       │
        │       ├── Car (concrete)
        │       └── Motorcycle (concrete)
        │
        └── Bicycle (concrete)    ← Implements all abstract
    
    === Bicycle (extends Vehicle directly) ===
  18. bicycle ← ⟨Bicycle C⟩

    39        Bicycle bicycle→ ⟨Bicycle C⟩ = new Bicycle("Trek", "FX3");40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));132    }133    134    @Override135    void accelerate() {136        System.out.println("Motorcycle accelerating fast!");137    }138    139    @Override140    void brake() {141        System.out.println("Motorcycle braking...");142    }143}144145// Alternative: Extends Vehicle directly  //?directextend146class Bicycle extends Vehicle {147    148    Bicycle(String brandTrek, String modelFX3) {149        super(brand, model);
  19. @Override void start()

    40        bicycle.displayInfo();41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));132    }133    134    @Override135    void accelerate() {136        System.out.println("Motorcycle accelerating fast!");137    }138    139    @Override140    void brake() {141        System.out.println("Motorcycle braking...");142    }143}144145// Alternative: Extends Vehicle directly  //?directextend146class Bicycle extends Vehicle {147    148    Bicycle(String brand, String model) {149        super(brand, model);150    }151    152    // Must implement ALL THREE abstract methods  //?allthree153    @Override154    void start() {155        System.out.println("Getting on the bicycle...");156    }
    outputGetting on the bicycle...
  20. @Override void accelerate()

    41        bicycle.start();42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));132    }133    134    @Override135    void accelerate() {136        System.out.println("Motorcycle accelerating fast!");137    }138    139    @Override140    void brake() {141        System.out.println("Motorcycle braking...");142    }143}144145// Alternative: Extends Vehicle directly  //?directextend146class Bicycle extends Vehicle {147    148    Bicycle(String brand, String model) {149        super(brand, model);150    }151    152    // Must implement ALL THREE abstract methods  //?allthree153    @Override154    void start() {155        System.out.println("Getting on the bicycle...");156    }157    158    @Override159    void accelerate() {160        System.out.println("Pedaling faster!");161    }
    outputPedaling faster!
  21. @Override void brake()

    42        bicycle.accelerate();43        bicycle.brake();44    }45}4647// Level 1: Top abstract class  //?level148abstract class Vehicle {49    protected String brand;50    protected String model;51    52    Vehicle(String brand, String model) {53        this.brand = brand;54        this.model = model;55    }56    57    void displayInfo() {58        System.out.println("Brand: " + brand);59        System.out.println("Model: " + model);60    }61    62    // Abstract methods - ALL subclasses must implement  //?topabstract63    abstract void start();64    abstract void accelerate();65    abstract void brake();66}6768// Level 2: Abstract subclass  //?level269abstract class MotorVehicle extends Vehicle {  //?abstractextends70    protected String engineType;71    72    MotorVehicle(String brand, String model, String engine) {73        super(brand, model);74        this.engineType = engine;75    }76    77    @Override78    void displayInfo() {79        super.displayInfo();80        System.out.println("Engine: " + engineType);81    }82    83    // Implement ONE abstract method  //?partialimpl84    @Override85    void start() {86        System.out.println("Starting " + engineType + " engine...");87    }88    89    // Leave accelerate() and brake() still abstract!  //?stillabstract90    // Subclasses must implement them91}9293// Level 3: Concrete class  //?level394class Car extends MotorVehicle {95    private int numDoors;96    97    Car(String brand, String model, int doors) {98        super(brand, model, "V6");99        this.numDoors = doors;100    }101    102    @Override103    void displayInfo() {104        super.displayInfo();105        System.out.println("Doors: " + numDoors);106    }107    108    // Must implement remaining abstract methods  //?carimpl109    @Override110    void accelerate() {111        System.out.println("Car accelerating smoothly...");112    }113    114    @Override115    void brake() {116        System.out.println("Car braking with ABS...");117    }118}119120class Motorcycle extends MotorVehicle {121    private boolean hasSidecar;122    123    Motorcycle(String brand, String model, boolean sidecar) {124        super(brand, model, "V-Twin");125        this.hasSidecar = sidecar;126    }127    128    @Override129    void displayInfo() {130        super.displayInfo();131        System.out.println("Sidecar: " + (hasSidecar ? "Yes" : "No"));132    }133    134    @Override135    void accelerate() {136        System.out.println("Motorcycle accelerating fast!");137    }138    139    @Override140    void brake() {141        System.out.println("Motorcycle braking...");142    }143}144145// Alternative: Extends Vehicle directly  //?directextend146class Bicycle extends Vehicle {147    148    Bicycle(String brand, String model) {149        super(brand, model);150    }151    152    // Must implement ALL THREE abstract methods  //?allthree153    @Override154    void start() {155        System.out.println("Getting on the bicycle...");156    }157    158    @Override159    void accelerate() {160        System.out.println("Pedaling faster!");161    }162    163    @Override164    void brake() {165        System.out.println("Squeezing hand brakes...");166    }
    outputSqueezing hand brakes...

Abstract class can extend another abstract class. Concrete class must implement all.

Template method pattern

Define algorithm structure, let subclasses fill in steps.

TemplateMethod.java
Replay: real traced execution (multi-file project)
// Template Method Design Pattern

public class TemplateMethod {
    public static void main(String[] args) {
        System.out.println("=== Template Method Pattern ===\n");

        System.out.println("--- Making Coffee ---");
        Beverage coffee = new Coffee();
        coffee.prepare();

        System.out.println("\n--- Making Tea ---");
        Beverage tea = new Tea();
        tea.prepare();

        System.out.println("\n=== Pattern Explanation ===");
        System.out.println("""
        Template Method Pattern:

        1. Abstract class defines the ALGORITHM skeleton
        2. Some steps are concrete (shared)
        3. Some steps are abstract (customized)
        4. Subclasses fill in the blanks

        prepare() is the TEMPLATE:
        - boilWater()     ← Same for all
        - brew()          ← Different for each
        - pourInCup()     ← Same for all
        - addCondiments() ← Different for each
        """);

        System.out.println("=== Another Example: Report Generator ===\n");

        Report pdf = new PDFReport();
        Report html = new HTMLReport();

        System.out.println("--- PDF Report ---");
        pdf.generate();

        System.out.println("\n--- HTML Report ---");
        html.generate();
    }
}

// Template Method in Beverage class
abstract class Beverage {

    // TEMPLATE METHOD - defines the algorithm
    final void prepare() {
        boilWater();       // Concrete - same for all
        brew();            // Abstract - subclass implements
        pourInCup();       // Concrete - same for all
        addCondiments();   // Abstract - subclass implements
    }

    // Concrete methods - shared implementation
    void boilWater() {
        System.out.println("1. Boiling water");
    }

    void pourInCup() {
        System.out.println("3. Pouring into cup");
    }

    // Abstract methods - subclass provides
    abstract void brew();
    abstract void addCondiments();
}

class Coffee extends Beverage {

    @Override
    void brew() {
        System.out.println("2. Dripping coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("4. Adding sugar and milk");
    }
}

class Tea extends Beverage {

    @Override
    void brew() {
        System.out.println("2. Steeping tea bag");
    }

    @Override
    void addCondiments() {
        System.out.println("4. Adding lemon and honey");
    }
}

// Another Template Method example
abstract class Report {

    // Template method
    final void generate() {
        openDocument();
        writeHeader();    // Abstract
        writeContent();   // Abstract
        writeFooter();    // Abstract
        closeDocument();
    }

    void openDocument() {
        System.out.println("Opening document...");
    }

    void closeDocument() {
        System.out.println("Closing document.");
    }

    // Abstract steps
    abstract void writeHeader();
    abstract void writeContent();
    abstract void writeFooter();
}

class PDFReport extends Report {

    @Override
    void writeHeader() {
        System.out.println("Writing PDF header with metadata");
    }

    @Override
    void writeContent() {
        System.out.println("Writing PDF content with images");
    }

    @Override
    void writeFooter() {
        System.out.println("Writing PDF footer with page numbers");
    }
}

class HTMLReport extends Report {

    @Override
    void writeHeader() {
        System.out.println("Writing <head> with CSS");
    }

    @Override
    void writeContent() {
        System.out.println("Writing <body> with HTML tags");
    }

    @Override
    void writeFooter() {
        System.out.println("Writing <footer> with links");
    }
}

  1. coffee ← ⟨Coffee A⟩

    3public class TemplateMethod {4    public static void main(String[] args) {5        System.out.println("=== Template Method Pattern ===\n");6        7        System.out.println("--- Making Coffee ---");8        Beverage coffee→ ⟨Coffee A⟩ = new Coffee();9        coffee.prepare();  //?preparecoffee
    output=== Template Method Pattern ===
    --- Making Coffee ---
  2. void boilWater()

    pass 1 of 2
    48final void prepare() {  //?finaltemplate49    boilWater();       // Concrete - same for all50    brew();            // Abstract - subclass implements51    pourInCup();       // Concrete - same for all52    addCondiments();   // Abstract - subclass implements53}5455// Concrete methods - shared implementation  //?concretemethods56void boilWater() {57    System.out.println("1. Boiling water");58}
    output1. Boiling water
  3. @Override void brew()

    49        boilWater();       // Concrete - same for all50        brew();            // Abstract - subclass implements51        pourInCup();       // Concrete - same for all52        addCondiments();   // Abstract - subclass implements53    }54    55    // Concrete methods - shared implementation  //?concretemethods56    void boilWater() {57        System.out.println("1. Boiling water");58    }59    60    void pourInCup() {61        System.out.println("3. Pouring into cup");62    }63    64    // Abstract methods - subclass provides  //?abstractsteps65    abstract void brew();66    abstract void addCondiments();67}6869class Coffee extends Beverage {70    71    @Override72    void brew() {  //?coffeebrew73        System.out.println("2. Dripping coffee through filter");74    }
    output2. Dripping coffee through filter
  4. void pourInCup()

    pass 1 of 2
    50    brew();            // Abstract - subclass implements51    pourInCup();       // Concrete - same for all52    addCondiments();   // Abstract - subclass implements53}5455// Concrete methods - shared implementation  //?concretemethods56void boilWater() {57    System.out.println("1. Boiling water");58}5960void pourInCup() {61    System.out.println("3. Pouring into cup");62}
    output3. Pouring into cup
  5. tea ← ⟨Tea B⟩

    8        Beverage coffee = new Coffee();9        coffee.prepare();  //?preparecoffee10        11        System.out.println("\n--- Making Tea ---");12        Beverage tea→ ⟨Tea B⟩ = new Tea();13        tea.prepare();  //?preparetea14        15        System.out.println("\n=== Pattern Explanation ===");16        System.out.println("""17        Template Method Pattern:18        19        1. Abstract class defines the ALGORITHM skeleton20        2. Some steps are concrete (shared)21        3. Some steps are abstract (customized)22        4. Subclasses fill in the blanks23        24        prepare() is the TEMPLATE:25        - boilWater()     ← Same for all26        - brew()          ← Different for each27        - pourInCup()     ← Same for all28        - addCondiments() ← Different for each29        """);30        31        System.out.println("=== Another Example: Report Generator ===\n");32        33        Report pdf = new PDFReport();34        Report html = new HTMLReport();35        36        System.out.println("--- PDF Report ---");37        pdf.generate();38        39        System.out.println("\n--- HTML Report ---");40        html.generate();41    }42}4344// Template Method in Beverage class  //?templateclass45abstract class Beverage {46    47    // TEMPLATE METHOD - defines the algorithm  //?template48    final void prepare() {  //?finaltemplate49        boilWater();       // Concrete - same for all50        brew();            // Abstract - subclass implements51        pourInCup();       // Concrete - same for all52        addCondiments();   // Abstract - subclass implements53    }54    55    // Concrete methods - shared implementation  //?concretemethods56    void boilWater() {57        System.out.println("1. Boiling water");58    }59    60    void pourInCup() {61        System.out.println("3. Pouring into cup");62    }63    64    // Abstract methods - subclass provides  //?abstractsteps65    abstract void brew();66    abstract void addCondiments();67}6869class Coffee extends Beverage {70    71    @Override72    void brew() {  //?coffeebrew73        System.out.println("2. Dripping coffee through filter");74    }75    76    @Override77    void addCondiments() {  //?coffeecondiments78        System.out.println("4. Adding sugar and milk");79    }
    output4. Adding sugar and milk
    
    --- Making Tea ---
  6. void boilWater()

    pass 2 of 2
    48final void prepare() {  //?finaltemplate49    boilWater();       // Concrete - same for all50    brew();            // Abstract - subclass implements51    pourInCup();       // Concrete - same for all52    addCondiments();   // Abstract - subclass implements53}5455// Concrete methods - shared implementation  //?concretemethods56void boilWater() {57    System.out.println("1. Boiling water");58}
    output1. Boiling water
  7. @Override void brew()

    49        boilWater();       // Concrete - same for all50        brew();            // Abstract - subclass implements51        pourInCup();       // Concrete - same for all52        addCondiments();   // Abstract - subclass implements53    }54    55    // Concrete methods - shared implementation  //?concretemethods56    void boilWater() {57        System.out.println("1. Boiling water");58    }59    60    void pourInCup() {61        System.out.println("3. Pouring into cup");62    }63    64    // Abstract methods - subclass provides  //?abstractsteps65    abstract void brew();66    abstract void addCondiments();67}6869class Coffee extends Beverage {70    71    @Override72    void brew() {  //?coffeebrew73        System.out.println("2. Dripping coffee through filter");74    }75    76    @Override77    void addCondiments() {  //?coffeecondiments78        System.out.println("4. Adding sugar and milk");79    }80}8182class Tea extends Beverage {83    84    @Override85    void brew() {  //?teabrew86        System.out.println("2. Steeping tea bag");87    }
    output2. Steeping tea bag
  8. void pourInCup()

    pass 2 of 2
    50    brew();            // Abstract - subclass implements51    pourInCup();       // Concrete - same for all52    addCondiments();   // Abstract - subclass implements53}5455// Concrete methods - shared implementation  //?concretemethods56void boilWater() {57    System.out.println("1. Boiling water");58}5960void pourInCup() {61    System.out.println("3. Pouring into cup");62}
    output3. Pouring into cup
  9. pdf ← ⟨PDFReport C⟩, html ← ⟨HTMLReport D⟩

    12        Beverage tea = new Tea();13        tea.prepare();  //?preparetea14        15        System.out.println("\n=== Pattern Explanation ===");16        System.out.println("""17        Template Method Pattern:18        19        1. Abstract class defines the ALGORITHM skeleton20        2. Some steps are concrete (shared)21        3. Some steps are abstract (customized)22        4. Subclasses fill in the blanks23        24        prepare() is the TEMPLATE:25        - boilWater()     ← Same for all26        - brew()          ← Different for each27        - pourInCup()     ← Same for all28        - addCondiments() ← Different for each29        """);30        31        System.out.println("=== Another Example: Report Generator ===\n");32        33        Report pdf→ ⟨PDFReport C⟩ = new PDFReport();34        Report html→ ⟨HTMLReport D⟩ = new HTMLReport();35        36        System.out.println("--- PDF Report ---");37        pdf.generate();38        39        System.out.println("\n--- HTML Report ---");40        html.generate();41    }42}4344// Template Method in Beverage class  //?templateclass45abstract class Beverage {46    47    // TEMPLATE METHOD - defines the algorithm  //?template48    final void prepare() {  //?finaltemplate49        boilWater();       // Concrete - same for all50        brew();            // Abstract - subclass implements51        pourInCup();       // Concrete - same for all52        addCondiments();   // Abstract - subclass implements53    }54    55    // Concrete methods - shared implementation  //?concretemethods56    void boilWater() {57        System.out.println("1. Boiling water");58    }59    60    void pourInCup() {61        System.out.println("3. Pouring into cup");62    }63    64    // Abstract methods - subclass provides  //?abstractsteps65    abstract void brew();66    abstract void addCondiments();67}6869class Coffee extends Beverage {70    71    @Override72    void brew() {  //?coffeebrew73        System.out.println("2. Dripping coffee through filter");74    }75    76    @Override77    void addCondiments() {  //?coffeecondiments78        System.out.println("4. Adding sugar and milk");79    }80}8182class Tea extends Beverage {83    84    @Override85    void brew() {  //?teabrew86        System.out.println("2. Steeping tea bag");87    }88    89    @Override90    void addCondiments() {  //?teacondiments91        System.out.println("4. Adding lemon and honey");92    }
    output4. Adding lemon and honey
    
    === Pattern Explanation ===
    Template Method Pattern:
    
    1. Abstract class defines the ALGORITHM skeleton
    2. Some steps are concrete (shared)
    3. Some steps are abstract (customized)
    4. Subclasses fill in the blanks
    
    prepare() is the TEMPLATE:
    - boilWater()     ← Same for all
    - brew()          ← Different for each
    - pourInCup()     ← Same for all
    - addCondiments() ← Different for each
    === Another Example: Report Generator ===
    --- PDF Report ---
  10. void openDocument()

    pass 1 of 2
    99final void generate() {100    openDocument();101    writeHeader();    // Abstract102    writeContent();   // Abstract103    writeFooter();    // Abstract104    closeDocument();105}106107void openDocument() {108    System.out.println("Opening document...");109}
    outputOpening document...
  11. @Override void writeHeader()

    100        openDocument();101        writeHeader();    // Abstract102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }114    115    // Abstract steps  //?reportabstract116    abstract void writeHeader();117    abstract void writeContent();118    abstract void writeFooter();119}120121class PDFReport extends Report {122    123    @Override124    void writeHeader() {125        System.out.println("Writing PDF header with metadata");126    }
    outputWriting PDF header with metadata
  12. @Override void writeContent()

    101        writeHeader();    // Abstract102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }114    115    // Abstract steps  //?reportabstract116    abstract void writeHeader();117    abstract void writeContent();118    abstract void writeFooter();119}120121class PDFReport extends Report {122    123    @Override124    void writeHeader() {125        System.out.println("Writing PDF header with metadata");126    }127    128    @Override129    void writeContent() {130        System.out.println("Writing PDF content with images");131    }
    outputWriting PDF content with images
  13. @Override void writeFooter()

    102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }114    115    // Abstract steps  //?reportabstract116    abstract void writeHeader();117    abstract void writeContent();118    abstract void writeFooter();119}120121class PDFReport extends Report {122    123    @Override124    void writeHeader() {125        System.out.println("Writing PDF header with metadata");126    }127    128    @Override129    void writeContent() {130        System.out.println("Writing PDF content with images");131    }132    133    @Override134    void writeFooter() {135        System.out.println("Writing PDF footer with page numbers");136    }
    outputWriting PDF footer with page numbers
  14. void closeDocument()

    pass 1 of 2
    36        System.out.println("--- PDF Report ---");37        pdf.generate();38        39        System.out.println("\n--- HTML Report ---");40        html.generate();41    }42}4344// Template Method in Beverage class  //?templateclass45abstract class Beverage {46    47    // TEMPLATE METHOD - defines the algorithm  //?template48    final void prepare() {  //?finaltemplate49        boilWater();       // Concrete - same for all50        brew();            // Abstract - subclass implements51        pourInCup();       // Concrete - same for all52        addCondiments();   // Abstract - subclass implements53    }54    55    // Concrete methods - shared implementation  //?concretemethods56    void boilWater() {57        System.out.println("1. Boiling water");58    }59    60    void pourInCup() {61        System.out.println("3. Pouring into cup");62    }63    64    // Abstract methods - subclass provides  //?abstractsteps65    abstract void brew();66    abstract void addCondiments();67}6869class Coffee extends Beverage {70    71    @Override72    void brew() {  //?coffeebrew73        System.out.println("2. Dripping coffee through filter");74    }75    76    @Override77    void addCondiments() {  //?coffeecondiments78        System.out.println("4. Adding sugar and milk");79    }80}8182class Tea extends Beverage {83    84    @Override85    void brew() {  //?teabrew86        System.out.println("2. Steeping tea bag");87    }88    89    @Override90    void addCondiments() {  //?teacondiments91        System.out.println("4. Adding lemon and honey");92    }93}9495// Another Template Method example  //?reporttemplate96abstract class Report {97    98    // Template method99    final void generate() {100        openDocument();101        writeHeader();    // Abstract102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }
    outputClosing document.
    
    --- HTML Report ---
  15. void openDocument()

    pass 2 of 2
    99final void generate() {100    openDocument();101    writeHeader();    // Abstract102    writeContent();   // Abstract103    writeFooter();    // Abstract104    closeDocument();105}106107void openDocument() {108    System.out.println("Opening document...");109}
    outputOpening document...
  16. @Override void writeHeader()

    100        openDocument();101        writeHeader();    // Abstract102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }114    115    // Abstract steps  //?reportabstract116    abstract void writeHeader();117    abstract void writeContent();118    abstract void writeFooter();119}120121class PDFReport extends Report {122    123    @Override124    void writeHeader() {125        System.out.println("Writing PDF header with metadata");126    }127    128    @Override129    void writeContent() {130        System.out.println("Writing PDF content with images");131    }132    133    @Override134    void writeFooter() {135        System.out.println("Writing PDF footer with page numbers");136    }137}138139class HTMLReport extends Report {140    141    @Override142    void writeHeader() {143        System.out.println("Writing <head> with CSS");144    }
    outputWriting <head> with CSS
  17. @Override void writeContent()

    101        writeHeader();    // Abstract102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }114    115    // Abstract steps  //?reportabstract116    abstract void writeHeader();117    abstract void writeContent();118    abstract void writeFooter();119}120121class PDFReport extends Report {122    123    @Override124    void writeHeader() {125        System.out.println("Writing PDF header with metadata");126    }127    128    @Override129    void writeContent() {130        System.out.println("Writing PDF content with images");131    }132    133    @Override134    void writeFooter() {135        System.out.println("Writing PDF footer with page numbers");136    }137}138139class HTMLReport extends Report {140    141    @Override142    void writeHeader() {143        System.out.println("Writing <head> with CSS");144    }145    146    @Override147    void writeContent() {148        System.out.println("Writing <body> with HTML tags");149    }
    outputWriting <body> with HTML tags
  18. @Override void writeFooter()

    102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }114    115    // Abstract steps  //?reportabstract116    abstract void writeHeader();117    abstract void writeContent();118    abstract void writeFooter();119}120121class PDFReport extends Report {122    123    @Override124    void writeHeader() {125        System.out.println("Writing PDF header with metadata");126    }127    128    @Override129    void writeContent() {130        System.out.println("Writing PDF content with images");131    }132    133    @Override134    void writeFooter() {135        System.out.println("Writing PDF footer with page numbers");136    }137}138139class HTMLReport extends Report {140    141    @Override142    void writeHeader() {143        System.out.println("Writing <head> with CSS");144    }145    146    @Override147    void writeContent() {148        System.out.println("Writing <body> with HTML tags");149    }150    151    @Override152    void writeFooter() {153        System.out.println("Writing <footer> with links");154    }
    outputWriting <footer> with links
  19. void closeDocument()

    pass 2 of 2
    39        System.out.println("\n--- HTML Report ---");40        html.generate();41    }42}4344// Template Method in Beverage class  //?templateclass45abstract class Beverage {46    47    // TEMPLATE METHOD - defines the algorithm  //?template48    final void prepare() {  //?finaltemplate49        boilWater();       // Concrete - same for all50        brew();            // Abstract - subclass implements51        pourInCup();       // Concrete - same for all52        addCondiments();   // Abstract - subclass implements53    }54    55    // Concrete methods - shared implementation  //?concretemethods56    void boilWater() {57        System.out.println("1. Boiling water");58    }59    60    void pourInCup() {61        System.out.println("3. Pouring into cup");62    }63    64    // Abstract methods - subclass provides  //?abstractsteps65    abstract void brew();66    abstract void addCondiments();67}6869class Coffee extends Beverage {70    71    @Override72    void brew() {  //?coffeebrew73        System.out.println("2. Dripping coffee through filter");74    }75    76    @Override77    void addCondiments() {  //?coffeecondiments78        System.out.println("4. Adding sugar and milk");79    }80}8182class Tea extends Beverage {83    84    @Override85    void brew() {  //?teabrew86        System.out.println("2. Steeping tea bag");87    }88    89    @Override90    void addCondiments() {  //?teacondiments91        System.out.println("4. Adding lemon and honey");92    }93}9495// Another Template Method example  //?reporttemplate96abstract class Report {97    98    // Template method99    final void generate() {100        openDocument();101        writeHeader();    // Abstract102        writeContent();   // Abstract103        writeFooter();    // Abstract104        closeDocument();105    }106    107    void openDocument() {108        System.out.println("Opening document...");109    }110    111    void closeDocument() {112        System.out.println("Closing document.");113    }
    outputClosing document.

Concrete method calls abstract methods - subclasses provide the specifics.

template method Algorithm skeleton in parent. Specific steps implemented by subclasses.

Exercise: Practical.java

Build a document processing system with abstract classes