OOP Intermediate
Abstract Classes
Partial Implementation
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.
// 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()
// }
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 ===@Override void makeSound()
pass 1 of 214 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!a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩
pass 1 of 214 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 ===@Override void makeSound()
pass 2 of 222 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!@Override void makeSound()
pass 2 of 222 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
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 ===@Override void makeSound()
pass 1 of 214 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!a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩
pass 1 of 214 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 ===@Override void makeSound()
pass 2 of 222 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!@Override void makeSound()
pass 2 of 222 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
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 ===@Override void makeSound()
pass 1 of 214 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!a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩
pass 1 of 214 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 ===@Override void makeSound()
pass 2 of 222 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!@Override void makeSound()
pass 2 of 222 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
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 ===@Override void makeSound()
pass 1 of 214 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!a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩
pass 1 of 214 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 ===@Override void makeSound()
pass 2 of 222 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!@Override void makeSound()
pass 2 of 222 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
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 ===@Override void makeSound()
pass 1 of 214 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!a1 ← ⟨Dog C⟩, a2 ← ⟨Cat D⟩
pass 1 of 214 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 ===@Override void makeSound()
pass 2 of 222 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!@Override void makeSound()
pass 2 of 222 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.
Mix abstract and concrete methods
Provide some implementation, require the rest.
// 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");
}
}
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 ===this.name ← Buddy
pass 1 of 345// Constructor in abstract class //?absconstructor46Animal(String nameBuddy) {47 this.name→ Buddy = nameBuddy;48}All 3 passes — pass 1 is the card above pass namethis.namedogcatbird1 Buddy Buddy ⟨Dog A⟩ — — 2 Whiskers Whiskers — ⟨Cat B⟩ — 3 Tweety Tweety — — ⟨Bird C⟩ 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); //?supercallcat ← ⟨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 ---void introduce()
pass 1 of 310 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 BuddyAll 3 passes — pass 1 is the card above pass namebird1 Buddy — 2 Whiskers ⟨Bird C⟩ 3 Tweety — @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!void sleep()
pass 1 of 212 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 ---@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!void sleep()
pass 2 of 217 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 ===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);@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!@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.
Constructors in abstract classes
Abstract classes can have constructors for subclasses.
// 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
}
}
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 ===this.name ← Alice, this.salary ← 85000.0, nextId ← 1001, this.employeeId ← 1000
pass 1 of 253// 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 Alicethis.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 Engineeringthis.name ← Bob, this.salary ← 75000.0, nextId ← 1002, this.employeeId ← 1001
pass 2 of 253// 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 Bobthis.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 ---void displayInfo()
pass 1 of 261// 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.0System.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@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 ---void displayInfo()
pass 2 of 261// 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.0System.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@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 ===this.name ← Clean Code, this.price ← 44.99
pass 1 of 2118// 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}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 }this.name ← Effective Java, this.price ← 0.0
pass 2 of 2118// 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}Product(String name)
124// Constructor with default price //?defaultprice125Product(String nameEffective Java) {126 this(name, 0.0); // Calls other constructorthis.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:void displayInfo()
pass 1 of 2129void displayInfo() {130 System.out.println("Product: " + nameClean Code);131 System.out.println("Price: $" + price44.99);132}outputProduct: Clean Code Price: $44.99System.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:void displayInfo()
pass 2 of 2129void displayInfo() {130 System.out.println("Product: " + nameEffective Java);131 System.out.println("Price: $" + price0.0);132}outputProduct: Effective Java Price: $0.0System.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.
// 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...");
}
}
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 ===this.brand ← Toyota, this.model ← Camry
pass 1 of 352Vehicle(String brandToyota, String modelCamry) {53 this.brand→ Toyota = brandToyota;54 this.model→ Camry = modelCamry;55}All 3 passes — pass 1 is the card above pass brandmodelenginedoorssidecarthis.brandthis.modelthis.engineTypethis.numDoorscarthis.hasSidecarbikebicycle1 Toyota Camry V6 4 — Toyota Camry V6 4 ⟨Car A⟩ — — — 2 Harley Sportster V-Twin — true Harley Sportster V-Twin — — true ⟨Motorcycle B⟩ — 3 Trek FX3 — — — Trek FX3 — — — — — ⟨Bicycle C⟩ this.engineType ← V6
pass 1 of 272MotorVehicle(String brandToyota, String modelCamry, String engineV6) {73 super(brand, model);74 this.engineType→ V6 = engineV6;75}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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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 }this.engineType ← V-Twin
pass 2 of 272MotorVehicle(String brandHarley, String modelSportster, String engineV-Twin) {73 super(brand, model);74 this.engineType→ V-Twin = engineV-Twin;75}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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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 ---void displayInfo()
pass 1 of 357void displayInfo() {58 System.out.println("Brand: " + brandToyota);59 System.out.println("Model: " + modelCamry);60}outputBrand: Toyota Model: CamryAll 3 passes — pass 1 is the card above pass brandmodel1 Toyota Camry 2 Harley Sportster 3 Trek FX3 System.out.println("Engine: " + engineType);
78void displayInfo() {79 super.displayInfo();80 System.out.println("Engine: " + engineTypeV6);81}outputEngine: V6System.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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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@Override void start()
pass 1 of 212 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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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...@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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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...@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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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 ---System.out.println("Engine: " + engineType);
78void displayInfo() {79 super.displayInfo();80 System.out.println("Engine: " + engineTypeV-Twin);81}outputEngine: V-TwinSystem.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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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@Override void start()
pass 2 of 218 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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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...@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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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!@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 class27 │28 ├── MotorVehicle (abstract) ← Still abstract!29 │ │30 │ ├── Car (concrete)31 │ └── Motorcycle (concrete)32 │33 └── 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) ===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);@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...@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!@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.
// 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");
}
}
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(); //?preparecoffeeoutput=== Template Method Pattern === --- Making Coffee ---void boilWater()
pass 1 of 248final 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@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 filtervoid pourInCup()
pass 1 of 250 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 cuptea ← ⟨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 ---void boilWater()
pass 2 of 248final 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@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 bagvoid pourInCup()
pass 2 of 250 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 cuppdf ← ⟨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 ---void openDocument()
pass 1 of 299final void generate() {100 openDocument();101 writeHeader(); // Abstract102 writeContent(); // Abstract103 writeFooter(); // Abstract104 closeDocument();105}106107void openDocument() {108 System.out.println("Opening document...");109}outputOpening document...@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@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@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 numbersvoid closeDocument()
pass 1 of 236 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 ---void openDocument()
pass 2 of 299final void generate() {100 openDocument();101 writeHeader(); // Abstract102 writeContent(); // Abstract103 writeFooter(); // Abstract104 closeDocument();105}106107void openDocument() {108 System.out.println("Opening document...");109}outputOpening document...@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@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@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 linksvoid closeDocument()
pass 2 of 239 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.
Exercise: Practical.java
Build a document processing system with abstract classes