Introduction
In Java programming, the abstract keyword provides a powerful mechanism for creating base classes that define a contract without providing full implementation. This article explores how abstract classes and abstract methods work and their practical applications.
Abstract Classes
When you declare a class with the abstract modifier, it becomes an abstract class. Key characteristics include:
- Cannot be instantiated: You cannot create objects directly from an abstract class using the
newoperator - Can serve as a type: Abstract classes can be used as reference types for declaring variables, enabling polymorphism at compile time
- Acts as a blueprint: Think of an abstract class as a half-finished product that requires subclasses to complete the implementation
The abstract modifier must appear before the class declaration keyword.
Abstract Methods
An abstract method is declared with the abstract modifier but contains no implementation. The implementation is replaced with a semicolon. Consider the following example:
abstract class Shape {
public abstract double calculateArea();
public abstract void draw();
}
Important rules for abstract methods:
- Any class containing at least one abstract method must be declared as abstract
- An abstract class does not need to contain only abstract methods—it can also have concrete methods with full implementations
- Subclasses must implement all abstract methods from the parent class, unless the subclass is also declared abstract
Inheritance and Implementation
When a subclass inherits from an abstract class, it must provide implementations for all abstract methods. If the subclass fails to implement any abstract method, it must also be declared as abstract. Here's a example:
abstract class Animal {
public abstract void makeSound();
public abstract void move();
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks: Woof woof!");
}
@Override
public void move() {
System.out.println("Dog runs on four legs");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat meows: Meow meow!");
}
@Override
public void move() {
System.out.println("Cat jumps silently");
}
}
Constructors in Abstract Classes
Abstract classes can have constructors, which are called when a subclass instance is created. This allows you to initialize common fields defined in the abstract class:
abstract class Vehicle {
protected String brand;
protected int speed;
public Vehicle(String brand, int speed) {
this.brand = brand;
this.speed = speed;
}
public abstract void start();
}
class Car extends Vehicle {
public Car(String brand, int speed) {
super(brand, speed);
}
@Override
public void start() {
System.out.println(brand + " car starts at " + speed + " km/h");
}
}
Polymorphism with Abstract Classes
One of the key benefits of abstract classes is polymorphism. You can declare a reference variable of an abstract type and assign it an instance of a concrete subclass:
public class Main {
public static void main(String[] args) {
Animal pet = new Dog();
pet.makeSound(); // Outputs: Dog barks: Woof woof!
Animal anotherPet = new Cat();
anotherPet.makeSound(); // Outputs: Cat meows: Meow meow!
// Using the array to hold different implementations
Animal[] animals = {new Dog(), new Cat()};
for (Animal animal : animals) {
animal.makeSound();
}
}
}
Key Rules Summary
When to Use Abstract Classes
Abstract classes are ideal when you want to:
- Create a common base with shared fields and methods
- Define a contract that subclasses must follow
- Provide some default implementations while forcing others to be customized
- Achieve polymorphism through a common parent type
By leveraging abstract classes and methods, you can design flexible and maintainable object-oriented systems that enforce consistent behavior across related classes.