Introduction
Inheritance is one of the four fundamental principles of Object-Oriented Programming (OOP) in Java. It allows a new class (subclass or derived class) to inherit properties and behaviors (fields and methods) from an existing class (superclass or base class). Inheritance promotes code reusability and establishes a natural hierarchical relationship between classes.
Table of Contents
- What is Inheritance?
- Benefits of Inheritance
- Implementing Inheritance in Java
- Types of Inheritance in Java
- The
super
Keyword - Method Overriding
- Real-World Examples
- Conclusion
1. What is Inheritance?
Inheritance is a mechanism in Java by which one class (the subclass) can inherit the fields and methods of another class (the superclass). This allows the subclass to reuse code from the superclass without having to rewrite it. The subclass can also add its own fields and methods or override existing ones.
2. Benefits of Inheritance
- Code Reusability: Inheritance allows you to reuse code from existing classes, reducing redundancy.
- Method Overriding: Subclasses can provide specific implementations for methods defined in the superclass.
- Hierarchical Organization: Inheritance helps to organize classes in a hierarchical manner, making the code more understandable and maintainable.
3. Implementing Inheritance in Java
Inheritance is implemented using the extends
keyword.
Example:
// Superclass
public class Animal {
public void eat() {
System.out.println("This animal eats food.");
}
}
// Subclass
public class Dog extends Animal {
public void bark() {
System.out.println("The dog barks.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat();
myDog.bark();
}
}
Output:
This animal eats food.
The dog barks.
4. Types of Inheritance in Java
Java supports the following types of inheritance:
1. Single Inheritance
In a single inheritance, a subclass inherits from one superclass. This is the simplest form of inheritance.
Definition
Single inheritance refers to a class inheriting from only one superclass. It is used to extend the functionality of a single base class by adding new features or overriding existing ones.
Example:
// Superclass
public class Animal {
public void eat() {
System.out.println("This animal eats food.");
}
}
// Subclass
public class Dog extends Animal {
public void bark() {
System.out.println("The dog barks.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat();
myDog.bark();
}
}
2. Multilevel Inheritance
In multilevel inheritance, a class is derived from another class, which is also derived from another class, forming a chain of inheritance.
Definition
Multilevel inheritance refers to a scenario where a class inherits from a subclass, making it part of a longer inheritance chain. This type of inheritance can extend the hierarchy and add layers of functionality.
Example:
// Superclass
public class Animal {
public void eat() {
System.out.println("This animal eats food.");
}
}
// Intermediate subclass
public class Mammal extends Animal {
public void breathe() {
System.out.println("This mammal breathes air.");
}
}
// Final subclass
public class Dog extends Mammal {
public void bark() {
System.out.println("The dog barks.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat();
myDog.breathe();
myDog.bark();
}
}
3. Hierarchical Inheritance
In hierarchical inheritance, multiple subclasses inherit from a single superclass.
Definition
Hierarchical inheritance occurs when multiple subclasses share the same superclass. It allows the subclasses to inherit common features from the superclass while also adding their own unique features.
Example:
// Superclass
public class Animal {
public void eat() {
System.out.println("This animal eats food.");
}
}
// Subclass 1
public class Dog extends Animal {
public void bark() {
System.out.println("The dog barks.");
}
}
// Subclass 2
public class Cat extends Animal {
public void meow() {
System.out.println("The cat meows.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
Cat myCat = new Cat();
myDog.eat();
myDog.bark();
myCat.eat();
myCat.meow();
}
}
4. Multiple Inheritance (Using Interfaces)
Java does not support multiple inheritance (a class inheriting from more than one class) directly to avoid complexity and ambiguity. However, multiple inheritance can be achieved using interfaces.
Definition
Multiple inheritance refers to a class inheriting from multiple classes. Java does not support multiple inheritance directly due to the “diamond problem,” but it can be simulated using interfaces. A class can implement multiple interfaces, thus achieving multiple inheritance-like behavior.
Example:
// Interface 1 interface CanFly { void fly(); } // Interface 2 interface CanSwim { void swim(); } // Class implementing multiple interfaces public class Duck implements CanFly, CanSwim { public void fly() { System.out.println("The duck flies."); } public void swim() { System.out.println("The duck swims."); } } public class Main { public static void main(String[] args) { Duck myDuck = new Duck(); myDuck.fly(); myDuck.swim(); } }
5. The super Keyword
The super
keyword in Java is used to refer to the immediate superclass of a subclass. It is commonly used to access superclass methods and constructors.
Example: Using super
to Call Superclass Constructor
// Superclass
public class Animal {
String name;
// Constructor
public Animal(String name) {
this.name = name;
}
public void display() {
System.out.println("Animal: " + name);
}
}
// Subclass
public class Dog extends Animal {
String breed;
// Constructor
public Dog(String name, String breed) {
super(name); // Call to superclass constructor
this.breed = breed;
}
public void display() {
super.display(); // Call to superclass method
System.out.println("Breed: " + breed);
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog("Buddy", "Golden Retriever");
myDog.display();
}
}
Output:
Animal: Buddy
Breed: Golden Retriever
6. Method Overriding
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. The overridden method in the subclass must have the same signature (name, return type, and parameters) as the method in the superclass.
Example: Method Overriding
// Superclass
public class Animal {
public void sound() {
System.out.println("This animal makes a sound.");
}
}
// Subclass
public class Cat extends Animal {
@Override
public void sound() {
System.out.println("The cat meows.");
}
}
public class Main {
public static void main(String[] args) {
Animal myCat = new Cat();
myCat.sound();
}
}
Output:
The cat meows.
7. Real-World Examples
Example: Vehicle Inheritance
Let’s implement a real-world example of inheritance in Java using a simple hierarchy of a vehicle.
Let’s say we have a basic Vehicle
class, and we want to create specific types of vehicles like Car
and Bike
that inherit properties from Vehicle
.
1. Vehicle Class (Parent Class)
class Vehicle {
String brand;
int speed;
// Constructor
public Vehicle(String brand, int speed) {
this.brand = brand;
this.speed = speed;
}
// Method to display vehicle details
public void displayInfo() {
System.out.println("Brand: " + brand + ", Speed: " + speed + " km/h");
}
}
2. Car Class (Child Class)
class Car extends Vehicle {
int numberOfDoors;
// Constructor
public Car(String brand, int speed, int numberOfDoors) {
super(brand, speed); // Calling the constructor of the parent class
this.numberOfDoors = numberOfDoors;
}
// Method to display car details
@Override
public void displayInfo() {
super.displayInfo(); // Calling the method of the parent class
System.out.println("Number of Doors: " + numberOfDoors);
}
}
3. Bike Class (Child Class)
class Bike extends Vehicle {
boolean hasCarrier;
// Constructor
public Bike(String brand, int speed, boolean hasCarrier) {
super(brand, speed); // Calling the constructor of the parent class
this.hasCarrier = hasCarrier;
}
// Method to display bike details
@Override
public void displayInfo() {
super.displayInfo(); // Calling the method of the parent class
System.out.println("Has Carrier: " + (hasCarrier ? "Yes" : "No"));
}
}
4. Main Class to Test Inheritance
public class Main {
public static void main(String[] args) {
Car car = new Car("Toyota", 120, 4);
Bike bike = new Bike("Yamaha", 80, true);
System.out.println("Car Details:");
car.displayInfo();
System.out.println("\nBike Details:");
bike.displayInfo();
}
}
Output:
Car Details:
Brand: Toyota, Speed: 120 km/h
Number of Doors: 4
Bike Details:
Brand: Yamaha, Speed: 80 km/h
Has Carrier: Yes
Explanation:
- Vehicle Class:
- The
Vehicle
class is the parent class with common properties likebrand
andspeed
. - It has a method
displayInfo()
that prints these properties.
- The
- Car and Bike Classes:
- Both
Car
andBike
classes inherit fromVehicle
using theextends
keyword. - They each have their own specific properties (
numberOfDoors
forCar
andhasCarrier
forBike
). - They override the
displayInfo()
method to include their specific details while still calling the parent class’s method usingsuper.displayInfo()
.
- Both
- Main Class:
- This class creates instances of
Car
andBike
, and calls theirdisplayInfo()
methods to show the inherited and specific properties.
- This class creates instances of
This example demonstrates how inheritance allows Car
and Bike
to reuse code from the Vehicle
class while adding their own specific properties and behaviors. This is a fundamental concept in object-oriented programming that helps reduce code duplication and improve maintainability.
Real-World Example of Java Inheritance: Employees and Managers
Let’s consider an example of a company where we have different types of employees. We can create a base class called Employee
, and then create a subclass called Manager
that inherits from Employee
. The Manager
class will have additional responsibilities or attributes, such as managing a team.
Base Class: Employee
class Employee {
String name;
int id;
double salary;
public Employee(String name, int id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public void displayDetails() {
System.out.println("Employee ID: " + id);
System.out.println("Name: " + name);
System.out.println("Salary: $" + salary);
}
}
Subclass: Manager
class Manager extends Employee {
String department;
public Manager(String name, int id, double salary, String department) {
super(name, id, salary); // Call to the constructor of the base class (Employee)
this.department = department;
}
public void displayDetails() {
super.displayDetails(); // Call the method from the base class to display common details
System.out.println("Department: " + department);
}
}
Main Class to Test Inheritance
public class Company {
public static void main(String[] args) {
Employee emp = new Employee("Rahul Sharma", 101, 50000);
emp.displayDetails();
System.out.println();
Manager mgr = new Manager("Priya Verma", 102, 75000, "IT");
mgr.displayDetails();
}
}
Output
Employee ID: 101
Name: Rahul Sharma
Salary: $50000.0
Employee ID: 102
Name: Priya Verma
Salary: $75000.0
Department: IT
Explanation
- Inheritance: The
Manager
class inherits from theEmployee
class using theextends
keyword. This meansManager
has access to the fields (name
,id
,salary
) and methods (displayDetails()
) of theEmployee
class. - Constructor Chaining: In the
Manager
class, the constructor callssuper(name, id, salary)
to invoke the constructor of theEmployee
class, ensuring that thename
,id
, andsalary
fields are properly initialized. - Method Overriding: The
displayDetails()
method in theManager
class overrides thedisplayDetails()
method in theEmployee
class. However, it still callssuper.displayDetails()
to reuse the code for displaying common details (ID, name, salary) and then adds the specific detail forManager
, which is the department. - Output: When the
displayDetails()
method is called on anEmployee
object, only the employee’s ID, name, and salary are displayed. When called on aManager
object, the method displays the same details as forEmployee
, plus the department information, showing how inheritance and method overriding work in Java.
This example demonstrates how inheritance allows for code reuse and extension, enabling subclasses to build upon the base class’s functionality.
8. Conclusion
Inheritance in Java is a powerful feature that promotes code reusability and hierarchical class organization. By understanding how to implement and use inheritance, including the use of the super
keyword and method overriding, you can create more flexible and maintainable code. Inheritance allows for building complex class structures that model real-world relationships effectively.