In this chapter, we will talk about inheritance, a fundamental pillar of object-oriented programming that facilitates code reuse and the creation of class hierarchies.
We will see how inheritance allows extending and modifying the behavior of a class, promoting a more efficient and organized design.
# What is Inheritance?
Inheritance is based on the "is a" relationship, a classification. In Mathematics, we could say that integers and reals are a subclass of number; in Zoology, we can say that an orca is a mammal.
Here we can see some cases:
Points to note:
-
Classifications don't have to be complex.
-
Location in the hierarchy is based on the "is a" relationship.
-
Each class inherits properties (attributes) and behavior (methods) from its ancestors.
-
Some classes may be abstract (they won't have instances).
-
In UML, it is modeled with an arrow pointing from the heir to the ancestor.
This mechanism allows one class to inherit attributes and methods from another class (superclass or base class).
This means you can create new classes on top of existing ones, extending, hierarchizing, and specializing their behavior without having to write everything from scratch.
# Base and Derived Classes
-
Base Class (Superclass, Ancestor): It is the class from which inheritance occurs, also called the Parent class. It defines common attributes and methods that will be shared by its subclasses.
-
Derived Class (Subclass, Heir): It is the class that inherits from the superclass, or Child class. It can add its own attributes and methods besides the inherited ones, and redefine behaviors (we will see this in the polymorphism chapter).
# Use of extends
In Java, we use the keyword extends to establish an inheritance relationship between two clases. The subclass extends the superclass.
# Overriding Methods
Subclasses can override the methods inherited from the superclass to provide a specific implementation.
This is done simply by defining a method in the subclass with the same signature as the method in the superclass.
# The super() Method
Linked to method overriding, the super() method is used to invoke, from the subclass, the overridden method of the superclass.
It is commonly used in constructors when the superclass has a constructor with arguments to initialize, but it can be used from any method.
# Single Inheritance vs Multiple Inheritance
In languages like C++, multiple inheritance is allowed, meaning a class can inherit from more than one class.
In Java and most languages, multiple inheritance is not allowed, meaning a class can only have one "Parent"; this simplifies coding.
# Practical Example: Class Hierarchy for Vehicles
We are going to create a class hierarchy to represent different types of vehicles: a generic vehicle, a car, and a motorcycle.
Base: Vehicle
public class Vehicle {
protected String brand;
protected String model;
public Vehicle(String brand, String model) {
this.brand = brand;
this.model = model;
}
public void showDetails() {
System.out.println("Brand: " + brand + ", Model: " + model);
}
}
Derived: Car
public class Car extends Vehicle {
private int numberOfDoors;
public Car(String brand, String model, int numberOfDoors) {
super(brand, model); // Call to superclass constructor
this.numberOfDoors = numberOfDoors;
}
// Overriding the showDetails method, replaces the parent's one
public void showDetails() {
super.showDetails(); // Call to superclass (parent) method
System.out.println("Number of Doors: " + numberOfDoors);
}
}
Derived: Motorcycle
public class Motorcycle extends Vehicle {
private boolean hasSidecar;
public Motorcycle(String brand, String model, boolean hasSidecar) {
super(brand, model); // Call to superclass constructor
this.hasSidecar = hasSidecar;
}
// Overriding the showDetails method, replaces the parent's one
public void showDetails() {
super.showDetails(); // Call to superclass method
System.out.println("Has Sidecar?: " + (hasSidecar ? "Yes" : "No"));
}
}
Using the Classes
Vehicle myCar = new Car("Toyota", "Corolla", 4);
myCar.showDetails();
Vehicle myMotorcycle = new Motorcycle("Harley-Davidson", "Street 750", false);
myMotorcycle.showDetails();
# Conclusions
Inheritance is a powerful tool in object-oriented programming that facilitates code extension and reuse.
It allows developers to build complex, hierarchical systems in a more intuitive and modular way, ensuring that the code is easy to understand and maintain.
Through inheritance, we can reduce redundancy, promote consistency, and adapt class behavior to meet the specific needs of our application.
As you progress, you will see how inheritance, along with polymorphism, becomes an essential component in the design of your software projects.