Abstract Classes
An abstract class is a class that cannot be instantiated directly. It's designed to be a base class that other classes extend. Abstract classes can contain both abstract methods (without implementation) and concrete methods (with implementation).
What is an Abstract Class?
An abstract class is declared with the abstract keyword. It represents an incomplete class that serves as a blueprint for subclasses.
abstract class Shape {
String color;
// Abstract method - no body, must be implemented by subclasses
abstract double calculateArea();
// Concrete method - has implementation
void setColor(String color) {
this.color = color;
}
}
Key Characteristics:
- Declared with
abstractkeyword - Cannot be instantiated (
new Shape()is invalid) - Can have constructors (called by subclasses)
- Can have both abstract and concrete methods
- Can have instance variables
Abstract Methods
An abstract method has no body - just a declaration. Subclasses must provide an implementation.
abstract class Animal {
// Abstract method - each animal sounds different
abstract void makeSound();
// Concrete method - all animals breathe the same way
void breathe() {
System.out.println("Breathing...");
}
}
class Dog extends Animal {
@Override
void makeSound() { // MUST implement abstract method
System.out.println("Woof!");
}
}
class Cat extends Animal {
@Override
void makeSound() { // MUST implement abstract method
System.out.println("Meow!");
}
}
Rules for Abstract Methods:
- No method body - ends with semicolon
- Can only exist in abstract classes or interfaces
- Cannot be
final,static, orprivate - Subclasses must implement all abstract methods (or be abstract themselves)
Constructors in Abstract Classes
Abstract classes can have constructors. They are called when a subclass object is created.
abstract class Vehicle {
String brand;
int year;
// Constructor in abstract class
Vehicle(String brand, int year) {
this.brand = brand;
this.year = year;
System.out.println("Vehicle constructor called");
}
abstract void start();
}
class Car extends Vehicle {
int numDoors;
Car(String brand, int year, int numDoors) {
super(brand, year); // Call abstract class constructor
this.numDoors = numDoors;
System.out.println("Car constructor called");
}
@Override
void start() {
System.out.println(brand + " car is starting");
}
}
Concrete Methods in Abstract Classes
Abstract classes can provide default implementations that subclasses inherit or override:
abstract class Employee {
String name;
double baseSalary;
Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
// Abstract - different for each type
abstract double calculateBonus();
// Concrete - same for all employees
double getTotalPay() {
return baseSalary + calculateBonus();
}
// Concrete - can be overridden if needed
void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Total Pay: $" + getTotalPay());
}
}
Output
Click Run to execute your code
When to Use Abstract Classes
- Shared code among related classes: When subclasses share common code
- Partial implementation: When you want to provide some default behavior but force subclasses to implement specific parts
- Template method pattern: Define the skeleton of an algorithm, letting subclasses fill in the details
- Access modifiers needed: When you need non-public methods (interfaces are implicitly public)
- Instance variables: When you need to share state among subclasses
Abstract Class vs Interface
| Abstract Class | Interface |
|---|---|
| Can have instance variables | Only constants (public static final) |
| Can have constructors | Cannot have constructors |
| Single inheritance only | Multiple implementation allowed |
| Any access modifier for methods | Methods are public by default |
| Use for IS-A relationship with shared code | Use for CAN-DO capability/behavior |
Rule of Thumb: Use abstract classes when classes share code and state. Use interfaces when classes share behavior but not implementation.
Common Mistakes
- Trying to instantiate an abstract class:
new Animal()is a compile error - Forgetting to implement all abstract methods: Subclass must implement ALL abstract methods or be declared abstract itself
- Making abstract methods private: Abstract methods must be accessible to subclasses
- Overusing abstract classes: Consider interfaces for defining capabilities
Summary
- Abstract classes cannot be instantiated directly
- Abstract methods have no body and must be implemented by subclasses
- Abstract classes can have constructors, instance variables, and concrete methods
- Use abstract classes when you have shared code among related classes
- A class that doesn't implement all abstract methods must itself be abstract
Enjoying these tutorials?