13.12 Inheritance and Polymorphism in Java: Interfaces
In the world of object-oriented programming (OOP), inheritance and polymorphism are two fundamental concepts that allow the creation of more organized, reusable and easier to maintain code. In Java, these concepts are implemented through classes and interfaces, which together provide a powerful framework for software development. In this chapter, we will explore how interfaces in Java enable the implementation of inheritance and polymorphism, and how you can use them to create more flexible and extensible programs.
What are Interfaces?
An interface in Java is a reference type similar to a class, which can contain constants and abstract methods. Unlike classes, interfaces cannot contain method implementations (except default and static methods as of Java 8) and cannot be instantiated. They are used to define a contract that classes must follow, that is, a set of methods that classes must implement.
Interfaces are particularly useful when you want to ensure that different classes implement the same functionality, but in potentially different ways. This is part of what we call polymorphism, where a single interface type can refer to multiple forms of implementations.
Inheritance through Interfaces
In Java, a class can inherit from only one parent class (superclass), but it can implement multiple interfaces. This is a form of multiple type inheritance, which allows a class to be viewed as several different types and therefore be used in different ways. Interface inheritance is done through the implements
keyword, and a class that implements an interface must provide concrete implementations for all of its abstract methods.
Interface Example
public interface Vehicle {
void accelerate(int increment);
void brake(int decrement);
}
In the example above, the Vehicle
interface defines two abstract methods: accelerate
and brake
. Any class that implements Vehicle
must provide implementations for these methods.
Implementing Interfaces
public class Car implements Vehicle {
private int speed;
@Override
public void accelerate(int increment) {
speed += increment;
}
@Override
public void brake(int decrement) {
speed -= decrement;
}
}
The Car
class implements the Vehicle
interface and provides concrete implementations of the accelerate
and brake
methods. Note that we use the @Override
annotation to indicate that we are overriding interface methods.
Polymorphism with Interfaces
Polymorphism is the ability of an object to be referenced in multiple ways. In Java, this is often accomplished through interfaces. For example, if we have another class, such as Bicycle
, which also implements the Vehicle
interface, we can reference both objects of type Car
and Bicycle
through a reference of type Vehicle
.
Vehicle myVehicle;
myVehicle = new Car();
myVehicle.accelerate(10);
myVehicle = new Bicycle();
myVehicle.accelerate(3);
In the example above, the variable myVehicle
is of the Vehicle
interface type. Initially, it references an object of type Car
and then an object of type Bicycle
. In both cases, we can call the accelerate
method without worrying about the specific type of the object.
Benefits of Interfaces
Interfaces bring several benefits to software development in Java:
- Clear contract: Interfaces define a clear set of methods that must be implemented, making it easier to understand how classes should be used.
- Decoupling: Because interfaces are abstractions, they allow you to write code that does not depend on specific implementations, making your code more flexible and easier to modify.
- Testability: Interfaces make it easy to create mock objects for testing, as you can create fake implementations that follow the interface contract.
- Extensibility: New classes can be easily added to the system, as long as they implement the necessary interfaces, without changing the existing code.
Conclusion
Inheritance and polymorphism are key concepts in OOP and, in Java, the interfaces ofplay a crucial role in implementing these concepts. They enable the creation of flexible and reusable code, facilitate system maintenance and extension, and promote good software design practices. By mastering the use of interfaces, you will be equipped to create robust, adaptable programs that can grow and evolve with ease.