Abstract Classes
Abstract classes define common behavior for related classes while leaving specific implementation to subclasses. They cannot be instantiated directly.
Abstract Class Definition
public abstract class Shape {
// Abstract method: no implementation (subclasses MUST implement)
public abstract double getArea();
public abstract double getPerimeter();
// Concrete method: has implementation (shared behavior)
public void display() {
System.out.println("Area: " + getArea());
}
}
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public double getPerimeter() {
return 2 * Math.PI * radius;
}
}
When to Use Abstract Classes
| Use When | Avoid When |
|---|---|
| Related classes share common behavior | Classes are unrelated |
| You need non-public members | You need multiple inheritance |
| You want to provide default implementations | You only define contracts |
| Control over versioning | Maximum flexibility needed |
Template Method Pattern
Abstract classes enable the Template Method pattern:
public abstract class DataParser {
// Template method (final: cannot be overridden)
public final void parse(String filePath) {
String data = readFile(filePath);
Object parsed = processData(data);
save(parsed);
}
// Abstract: subclasses must implement
protected abstract Object processData(String data);
// Concrete: shared implementation
protected String readFile(String path) { ... }
protected void save(Object data) { ... }
}
public class CSVParser extends DataParser {
@Override
protected Object processData(String data) {
// CSV-specific parsing
}
}
public class JSONParser extends DataParser {
@Override
protected Object processData(String data) {
// JSON-specific parsing
}
}
Abstract Class vs Regular Class
Regular Class
├── Can be instantiated
├── All methods can have implementations
└── Can exist without subclasses
Abstract Class
├── Cannot be instantiated directly
├── Can have abstract methods (no body)
├── Requires subclasses for abstract methods
└── Provides partial implementation
Interfaces
Interfaces define contracts that classes must follow. They specify what a class can do without defining how it does it.
Interface Definition
public interface PaymentProcessor {
// Method signature (no body in older Java)
PaymentResult processPayment(Money amount, PaymentDetails details);
boolean refund(String transactionId, Money amount);
// Constant (implicitly public static final)
int MAX_RETRY_ATTEMPTS = 3;
}
// Implementation
public class StripePaymentProcessor implements PaymentProcessor {
@Override
public PaymentResult processPayment(Money amount, PaymentDetails details) {
// Stripe-specific implementation
}
@Override
public boolean refund(String transactionId, Money amount) {
// Stripe-specific implementation
}
}
Interface Design Principles
1. Interface Segregation (ISP):
// Bad: Fat interface
class OrderService implements Readable, Writable, Deletable, Searchable {
// Forced to implement methods you might not need
}
// Good: Segregated interfaces
class OrderService implements Readable, Writable {
// Only implement what's needed
}
2. Programming to Interface:
// Bad: Depends on concrete class
StripePaymentProcessor processor = new StripePaymentProcessor();
// Good: Depends on interface
PaymentProcessor processor = new StripePaymentProcessor();
3. Default Methods (Java 8+):
public interface Logger {
void log(String message);
// Default implementation
default void logError(String message) {
log("ERROR: " + message);
}
}
Interface Methods
| Method Type | Purpose | Example |
|---|---|---|
| Abstract | Must be implemented | void save(); |
| Default | Optional override | default void log() {} |
| Static | Utility methods | static Validator create() {} |
Multiple Interface Implementation
public interface Serializable { }
public interface Comparable<T> { }
public interface Cloneable { }
// Java allows implementing multiple interfaces
public class User implements Serializable, Comparable<User>, Cloneable {
@Override
public int compareTo(User other) { ... }
}
When to Use Each
Choosing between abstract classes and interfaces depends on design goals. This chapter provides a decision framework.
Decision Matrix
┌─────────────────────────────────────────────────────────────┐
│ Abstract Class vs Interface │
├──────────────────┬───────────────────┬──────────────────────┤
│ Criteria │ Abstract Class │ Interface │
├──────────────────┼───────────────────┼──────────────────────┤
│ State (fields) │ ✓ Can have │ ✗ Only constants │
│ Constructors │ ✓ Yes │ ✗ No │
│ Multiple inherit │ ✗ Single only │ ✓ Multiple │
│ Access modifiers │ ✓ Any │ ✗ public only │
│ Relationship │ IS-A (strong) │ CAN-DO (capability) │
│ Versioning │ Easier │ Harder │
│ Flexibility │ Lower │ Higher │
└──────────────────┴───────────────────┴──────────────────────┘
Choose Abstract Class When:
1. Shared state and behavior:
// Abstract class: shares state (fields) and behavior
public abstract class Account {
protected double balance; // Shared state
protected String id; // Shared state
public void deposit(double amount) { // Shared behavior
balance += amount;
}
public abstract double calculateInterest(); // Varies
}
2. Template Method pattern:
public abstract class GameEngine {
public final void play() {
initialize();
while (!isGameOver()) {
processTurn();
}
announceWinner();
}
protected abstract void processTurn();
}
Choose Interface When:
1. Unrelated classes share capability:
// Unrelated classes can be Comparable
public class Student implements Comparable<Student> { }
public class Product implements Comparable<Product> { }
public class Employee implements Comparable<Employee> { }
2. Multiple capabilities:
public class SmartPhone implements Camera, Phone, GPS, MusicPlayer {
// Can have multiple capabilities
}
3. API contracts:
// Interface defines the contract
public interface UserRepository {
User findById(String id);
List<User> findAll();
void save(User user);
}
// Any implementation must follow this contract
Hybrid Approach
// Abstract class provides partial implementation
public abstract class AbstractRepository<T> {
protected EntityManager em;
public T findById(String id) {
return em.find(getType(), id);
}
public abstract Class<T> getType();
public void save(T entity) {
em.persist(entity);
}
}
// Interface defines capability
public interface SoftDeletable {
void softDelete();
boolean isDeleted();
}
// Concrete class uses both
public class UserRepository extends AbstractRepository<User>
implements SoftDeletable {
@Override
public Class<User> getType() { return User.class; }
@Override
public void softDelete() { ... }
}
Rule of Thumb
- Use interfaces for capabilities (
Comparable,Serializable) - Use abstract classes for partial implementations of related classes
- Prefer interfaces when unsure — they're more flexible
- Use both when you need shared state AND multiple capabilities
Practice Problems
Design a scalable Abstraction system. Cover high-level architecture, data model, and API design.
Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliabilityHow would you scale Abstraction to handle 10x the current load? Identify bottlenecks and solutions.
Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decompositionAnalyze potential failure modes for Abstraction and design mitigation strategies.
Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradationQuiz
1. Can an abstract class be instantiated directly?
2. When should you prefer an interface over an abstract class?
3. What is the Template Method pattern?
4. What is the difference between IS-A and CAN-DO relationships?
5. Which is NOT a valid reason to use an abstract class?
Flashcards
Question
What is an abstract class?
Click to reveal answer
Answer
A class that cannot be instantiated directly and may contain abstract methods (without implementation) that subclasses must implement. It provides partial implementation for related classes.
Question
What is an interface?
Click to reveal answer
Answer
A contract that defines methods a class must implement. Interfaces specify what a class can do without defining how. They enable multiple inheritance of type.
Question
What is the Template Method pattern?
Click to reveal answer
Answer
A pattern where an abstract class defines the skeleton of an algorithm (final method) with abstract steps that subclasses implement. The algorithm structure stays fixed; steps vary.
Question
Abstract class vs interface: state?
Click to reveal answer
Answer
Abstract classes can have instance fields (state). Interfaces can only have public static final constants. Use abstract class when you need shared state.
Question
When to prefer interfaces over abstract classes?
Click to reveal answer
Answer
When unrelated classes share a capability, when you need multiple inheritance of type, for API contracts, or when you need maximum flexibility.
Revision Notes
Key Takeaways
- 1.Abstract classes provide partial implementation; interfaces define pure contracts
- 2.Abstract classes share state; interfaces share capability
- 3.Use Template Method pattern for algorithm skeletons in abstract classes
- 4.Prefer interfaces when flexibility and multiple inheritance are needed
- 5.Choose based on relationship: IS-A → abstract class, CAN-DO → interface
Interview Tips
- •Explain why you chose abstract class vs interface in your design
- •Show how Template Method pattern enforces algorithm structure
- •Discuss Interface Segregation when designing multiple related interfaces
- •Mention programming to interface principle when showing dependency management
Cheat Sheet
Abstraction - Cheat Sheet
Abstract Class:
- Cannot instantiate directly
- Can have state (fields)
- Can have constructors
- Single inheritance
- IS-A relationship
- Use for related classes with shared behavior
Interface:
- Cannot have state (only constants)
- No constructors
- Multiple implementation
- CAN-DO relationship
- Use for capabilities/contracts
Decision:
| Need | Choice |
|---|---|
| Shared state | Abstract class |
| Multiple types | Interface |
| Template method | Abstract class |
| Unrelated capabilities | Interface |
| Default implementations | Both (Java 8+) |
Template Method:
Abstract class defines algorithm skeleton.
Subclasses implement specific steps.