Abstract Classes
Abstract Classes
Abstract classes cannot be instantiated and may contain abstract methods.
Basic Abstract Class
public abstract class Shape {
String color;
public Shape(String color) {
this.color = color;
}
// Abstract method - no implementation
public abstract double area();
public abstract double perimeter();
// Concrete method - has implementation
public String getColor() {
return color;
}
}
// Shape s = new Shape("red"); // COMPILE ERROR!
Concrete Subclass
public class Circle extends Shape {
double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public double perimeter() {
return 2 * Math.PI * radius;
}
}
public class Rectangle extends Shape {
double width, height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
@Override
public double perimeter() {
return 2 * (width + height);
}
}
Abstract Class Features
public abstract class Example {
// Can have constructors
public Example() { }
// Can have instance variables
private int count;
// Can have concrete methods
public void increment() { count++; }
// Can have abstract methods
public abstract void doSomething();
// Can have static methods
public static void utility() { }
// Can have final methods
public final void fixed() { }
}
When to Use Abstract Class
// USE abstract class when:
// 1. Shared state (fields) among subclasses
// 2. Common implementation of some methods
// 3. Constructor chaining needed
// 4. Non-public members needed
// Example:
public abstract class Vehicle {
protected int speed; // Shared state
protected double fuel;
// Common implementation
public void start() {
System.out.println("Vehicle starting");
}
// Abstract - each vehicle different
public abstract void drive();
}
Abstract Methods
Abstract Methods
Abstract methods have no implementation and must be overridden.
Declaration
public abstract class Animal {
// Abstract method - no body
public abstract void makeSound();
// Abstract method with parameters
public abstract void eat(String food);
}
// Subclass MUST implement all abstract methods
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
@Override
public void eat(String food) {
System.out.println("Dog eats " + food);
}
}
Partial Implementation
public abstract class Database {
// Abstract methods
public abstract void connect();
public abstract void disconnect();
public abstract void query(String sql);
// Concrete methods
public void log(String message) {
System.out.println("[LOG] " + message);
}
public boolean isConnected() {
return true;
}
}
// Subclass only needs to implement abstract methods
public class MySQLDatabase extends Database {
@Override
public void connect() { }
@Override
public void disconnect() { }
@Override
public void query(String sql) { }
// log() and isConnected() inherited as-is
}
Abstract Method Rules
public abstract class Example {
// Valid abstract methods
public abstract void method1();
protected abstract void method2();
abstract void method3(); // Package-private
// INVALID:
// private abstract void method(); // Can't be private
// static abstract void method(); // Can't be static
// final abstract void method(); // Can't be final
}
Abstract Class vs Interface
Abstract Class vs Interface
| Feature | Abstract Class | Interface |
|---|---|---|
| Multiple inheritance | No | Yes |
| Constructors | Yes | No |
| Instance variables | Yes | Only constants |
| Method implementation | Yes | Yes (Java 8+) |
| Access modifiers | Any | public (default) |
When to Use Abstract Class
// USE abstract class when:
// 1. Shared state among subclasses
// 2. Need constructors
// 3. Need non-public members
// 4. Have some common implementation
public abstract class Employee {
protected String name;
protected double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public abstract double calculateBonus();
public void printInfo() {
System.out.println(name + ": " + salary);
}
}
When to Use Interface
// USE interface when:
// 1. No shared state
// 2. Multiple inheritance needed
// 3. Define contract for unrelated classes
// 4. Type checking
public interface Serializable { }
public interface Comparable<T> { }
public interface Runnable { }
// Class can implement multiple interfaces
public class Employee implements Serializable, Comparable<Employee> {
// Must implement Comparable's compareTo method
}
Multiple Interfaces
// Abstract class: only one parent
public class Dog extends Animal { } // Only Animal
// Interface: multiple
public class Dog extends Animal implements Pet, Serializable {
// Can have multiple interfaces
}
Design Guidelines
// 1. Use interface for capability
public interface Flyable {
void fly();
}
// 2. Use abstract class for partial implementation
public abstract class Bird implements Flyable {
String name;
public abstract void fly();
}
// 3. Use interface for type checking
public void process(Flyable f) {
f.fly();
}
Practice Problems
Design a chess game with different piece types.
Example:
Input: new Pawn().move()
Output: moved
Each piece has different movement
Optimal Solution — O(1) time, O(1) space
Abstract Piece class with concrete subclasses.
abstract class Piece {
int row, col;
abstract List<int[]> getPossibleMoves();
abstract boolean canMoveTo(int row, int col);
}
class Pawn extends Piece {
List<int[]> getPossibleMoves() { /* pawn moves */ }
}
class Rook extends Piece {
List<int[]> getPossibleMoves() { /* rook moves */ }
}Edge Cases:
- Piece at edge
- Capture opponent
- Check conditions
Design notification system with email, SMS, push notifications.
Example:
Input: send(EmailNotification), send(SMSNotification)
Output: sent
Different notification types
Optimal Solution — O(1) time, O(1) space
Abstract Notification class with concrete types.
abstract class Notification {
abstract void send(String message);
}
class EmailNotification extends Notification {
void send(String message) { /* send email */ }
}
class SMSNotification extends Notification {
void send(String message) { /* send SMS */ }
}Edge Cases:
- Empty message
- Invalid phone
- Failed delivery
Quiz
1. Can you instantiate an abstract class?
2. What is an abstract method?
3. When should you use abstract class vs interface?
4. What is the primary purpose of Abstraction?
Flashcards
Question
What is an abstract class?
Click to reveal answer
Answer
A class that cannot be instantiated and may contain abstract methods without implementation.
Question
What is an abstract method?
Click to reveal answer
Answer
A method without implementation that must be overridden by concrete subclasses.
Question
What is the difference between abstract class and interface?
Click to reveal answer
Answer
Abstract class can have constructors and state. Interface cannot have constructors and has limited state (constants only).
Question
What is Abstraction?
Click to reveal answer
Answer
Abstraction is a key concept in Java programming.
Question
When to use Abstraction?
Click to reveal answer
Answer
Use Abstraction when building production systems that require reliability, scalability, and maintainability.
Revision Notes
Key Takeaways
- 1.Abstract classes cannot be instantiated
- 2.Abstract methods must be overridden
- 3.Abstract class for shared state, interface for contracts
- 4.Java supports single class inheritance only
Interview Tips
- •Know when to use abstract class vs interface
- •Understand abstract method rules
- •Practice designing with abstraction
- •Know limitations of abstract classes
Cheat Sheet
Cheat Sheet
- abstract class: cannot instantiate
- abstract method: no implementation
- abstract class vs interface: constructors, state, multiple inheritance
- Use abstract class for shared state
- Use interface for contracts