13. Inheritance and Polymorphism in Java
Object-oriented programming (OOP) is a programming paradigm that uses objects and their interactions to design and program applications. Java is a programming language that fully supports OOP, and two of its fundamental concepts are inheritance and polymorphism. These concepts allow for the creation of more modular, flexible and reusable code.
Inheritance in Java
Inheritance is a mechanism by which a new class, known as a subclass, can inherit fields and methods from another class, called a superclass. Inheritance allows subclasses to have a common starting point, sharing characteristics and behaviors, thus avoiding code duplication.
class Vehicle {
protected String brand;
public void honk() {
System.out.println("Beep! Beep!");
}
}
class Car extends Vehicle {
private int numberOfPortas;
public void displayInformation() {
System.out.println("Brand: " + brand + ", Ports: " + numberOfPortas);
}
}
In the example above, the Car
class inherits from the Vehicle
class. This means that Car
can access the brand
field and the horn()
method of the Vehicle
class. The extends
keyword is used to establish this inheritance relationship in Java.
Polymorphism in Java
Polymorphism is the ability of an object to be referenced in multiple ways. More specifically, it is the ability of a method to be implemented in several different ways. In Java, polymorphism can be achieved through the use of overridden and overloaded methods.
An overridden method is one that is inherited from a superclass and redefined in the subclass. This allows the subclass to provide a specific implementation for that method. The @Override
annotation is commonly used to indicate that a method is being overridden.
class Vehicle {
public void honk() {
System.out.println("Beep! Beep!");
}
}
class Car extends Vehicle {
@Override
public void honk() {
System.out.println("Honk! Honk!");
}
}
In the example above, the Car
class overrides the horn()
method of the Vehicle
class, providing its own implementation.
Polymorphism also allows an object of a subclass to be treated as if it were an object of its superclass. This is particularly useful when dealing with collections of objects that share a common base class.
Vehicle myVehicle = new Car();
myVehicle.horn(); // Calls the honk() method of the Car class
Here, myVehicle
is a reference of type Vehicle
, but points to an instance of Car
. When the horn()
method is called, the overridden implementation in Car
is executed.
Important Considerations about Inheritance and Polymorphism
Although inheritance and polymorphism are powerful, they should be used with caution. Excessive or inappropriate inheritance can lead to a confusing and difficult to maintain class structure. It is important to follow the principle of "least knowledge" and only expose what is necessary. Additionally, composition can often be a more flexible alternative to inheritance.
Polymorphism, on the other hand, when used wisely, can make code more generic and reusable. For example, a function that operates on objects of type Vehicle
can work with any subclass of Vehicle
, without needing to know the specific details of each subclass.
Conclusion
Inheritance and polymorphism are fundamental in object-oriented programming in Java. They allow developers to build extensible and reusable systems, reducing code redundancy and improving maintainability. At the same time, it is essential to use these concepts thoughtfully and understand their implications for software design. With practice and experience, programmers can master the effective use of inheritance and polymorphism to create robust and flexible Java applications.