Inheritance means acquiring the properties and methods of another class, just like a child inherits properties from their parents.
In simple words, inheritance helps us to reuse code that has already been written, instead of writing it again.
Real-Life Example to Understand Inheritance
Imagine a Parent class called Animal and a Child class called Dog. Here, a Dog is an animal, so it should have all the properties of an animal, like eating and sleeping. But it can also have its own special behavior, like barking.
The same things we used in Java, using inheritance, child classes use the parent class’s code and add their own features.
Syntax of Inheritance
class ParentClass {
// properties and methods of parent
}
class ChildClass extends ParentClass {
// properties and methods of child
}
In this syntax:
- The extends keyword is used to create inheritance.
- The ChildClass inherits everything from ParentClass (except private members).
Why Use Inheritance in Java?
1) Code Reusability: We don’t need to write same methods or variables again in every class, you can define them once in a parent class, and all child classes can automatically use them.
2) Extensibility: If you want to add a new behavior or functionality, you can simply extend an existing class and add new features without touching the original code.
Suppose you already have a Car class. Now you want to create an ElectricCar, instead of writing everything again, you can just extend Car and add electric-specific features like chargeBattery().
3) Simplified Maintenance: We can easily maintain the multiple classes because all the classes are shared same behavior.
If your parent class Employee has a calculateSalary() method, and the formula changes, you only need to update it in one place; all subclasses like Manager, Intern, or Engineer will automatically use the updated logic.
4) Polymorphism: Inheritance allows polymorphism, meaning the same method name can behave differently based on the object.
This is done through method overriding, where a child class provides its own version of a method defined in the parent class.
What is Method Overriding in Java?
Method Overriding in Java means redefining a method of the parent class inside the child class with the same name, same parameters, and same return type.
It allows the child class to give its own version of a method that already exists in the parent class.
Rules of Method Overriding
- Same Method Signature: The method name, parameters, and return type must be identical to the parent class.
- Inheritance Required: Overriding happens only when one class inherits another (extends keyword).
- Access Modifier: The child class cannot make the overridden method more restrictive.
- @Override Annotation (Recommended): It’s not mandatory, but it helps the compiler verify that the method is correctly overridden.
Simple example:
class Bird {
void makeSound() {
System.out.println("The bird chirps.");
}
}
class Parrot extends Bird {
@Override
void makeSound() {
System.out.println("The parrot talks!");
}
}
public class Main {
public static void main(String[] args) {
Bird myBird = new Parrot(); // Reference of parent, object of child
myBird.makeSound(); // Calls overridden method in child class
}
}
Output:
The parrot talks!
In this code:
- The parent class Bird has a method makeSound().
- The child class Parrot overrides that method to give a new definition.
Types of Inheritance in Java
Java supports the following types of inheritance:
- Single Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
Examples of Java Inheritance
1. Single Inheritance
In single inheritance, one child class inherits from one parent class. It’s the simplest and most commonly used form of inheritance.
Code example:
class Vehicle {
void start() {
System.out.println("The vehicle starts.");
}
}
class Car extends Vehicle {
void drive() {
System.out.println("The car is being driven.");
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.start(); // Inherited from Vehicle
myCar.drive(); // Defined in Car
}
}
Output:
The vehicle starts.
The car is being driven.
- Here, Car inherits the start() method from Vehicle.
2. Multilevel Inheritance
In multilevel inheritance, a class inherits from another class, which itself inherits from a third class. It creates a chain-like hierarchy where features pass down multiple levels.
Code example:
class Device {
void powerOn() {
System.out.println("The device is now on.");
}
}
class Laptop extends Device {
void type() {
System.out.println("You can type using the laptop.");
}
}
class GamingLaptop extends Laptop {
void playGame() {
System.out.println("Playing games on a high-performance laptop.");
}
}
public class Main {
public static void main(String[] args) {
GamingLaptop gl = new GamingLaptop();
gl.powerOn(); // From Device
gl.type(); // From Laptop
gl.playGame(); // From GamingLaptop
}
}
Output:
The device is now on.
You can type using the laptop.
Playing games on a high-performance laptop.
- Here, GamingLaptop inherits features from both Laptop and Device.
3. Hierarchical Inheritance
In hierarchical inheritance, multiple child classes inherit from a single parent class. Each subclass can use the parent’s features but also define its own behaviors.
Code example:
class Appliance {
void plugIn() {
System.out.println("The appliance is plugged in.");
}
}
class WashingMachine extends Appliance {
void washClothes() {
System.out.println("Washing clothes in progress.");
}
}
class Refrigerator extends Appliance {
void coolFood() {
System.out.println("The refrigerator keeps food fresh.");
}
}
public class Main {
public static void main(String[] args) {
WashingMachine wm = new WashingMachine();
wm.plugIn();
wm.washClothes();
Refrigerator rf = new Refrigerator();
rf.plugIn();
rf.coolFood();
}
}
Output:
The appliance is plugged in.
Washing clothes in progress.
The appliance is plugged in.
The refrigerator keeps food fresh.
- Both WashingMachine and Refrigerator inherit the plugIn() method from Appliance,
But each class has its own specialized action.
Final Keyword in Inheritance
The final keyword is used to stop changes; it can stop inheritance, method overriding, or variable modification, depending on where it is used.
1) Final Class – Cannot Be Inherited
When you declare a class as final, it means no other class can extend it. This is helpful when you want to make a fully secure or completed class.
Example:
final class Vehicle {
void message() {
System.out.println("This is a vehicle class.");
}
}
// This will cause an error because Vehicle is final
class Car extends Vehicle {
void message() {
System.out.println("This is a car class.");
}
}
- Here, Vehicle is declared as final, so the Car class cannot extend it.
2) Final Method – Cannot Be Overridden
A method declared with the final keyword cannot be overridden in a subclass. This ensures that the method’s logic remains fixed and unchangeable, even if another class inherits it.
Example:
class Parent {
final void showMessage() {
System.out.println("Message from Parent class.");
}
}
class Child extends Parent {
// Trying to override will cause an error
// void showMessage() {
// System.out.println("Message from Child class.");
// }
}
Disadvantages of Inheritance
- High Dependency Between Classes: When a class inherits from another, the child becomes dependent on the parent. If any small change happens in the parent class, it can affect all child classes.
- Inflexibility During Changes: Sometimes, when requirements change, it becomes hard to update the structure of an inherited system.
Mini Project: “Smart School Management System”
We’ll create a small console-based project that shows how inheritance works in a real-world scenario.
Code: SmartSchool.java
// Base class: Person
class Person {
private String name;
private int age;
// Constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
// Common method for all persons
void introduce() {
System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
}
// Getters for name and age
String getName() {
return name;
}
int getAge() {
return age;
}
}
// Derived class: Student
class Student extends Person {
private int rollNumber;
private String grade;
// Constructor
Student(String name, int age, int rollNumber, String grade) {
super(name, age); // calling parent constructor
this.rollNumber = rollNumber;
this.grade = grade;
}
// Overriding introduce() method
@Override
void introduce() {
System.out.println("I'm " + getName() + ", a student of grade " + grade + ".");
}
void showDetails() {
System.out.println("Roll Number: " + rollNumber);
System.out.println("Age: " + getAge());
System.out.println("Grade: " + grade);
}
}
// Derived class: Teacher
class Teacher extends Person {
private String subject;
private int experience;
// Constructor
Teacher(String name, int age, String subject, int experience) {
super(name, age);
this.subject = subject;
this.experience = experience;
}
// Overriding introduce() method
@Override
void introduce() {
System.out.println("I'm " + getName() + ", a teacher of " + subject + ".");
}
void showDetails() {
System.out.println("Subject: " + subject);
System.out.println("Experience: " + experience + " years");
System.out.println("Age: " + getAge());
}
}
// School class demonstrating inheritance in action
public class SmartSchool {
public static void main(String[] args) {
// Creating student and teacher objects
Student s1 = new Student("Riya", 15, 102, "10th Grade");
Teacher t1 = new Teacher("Mr. Sharma", 40, "Mathematics", 12);
// Demonstrating polymorphism and inheritance
System.out.println("----- SCHOOL INTRODUCTIONS -----");
s1.introduce();
t1.introduce();
System.out.println("\n----- STUDENT DETAILS -----");
s1.showDetails();
System.out.println("\n----- TEACHER DETAILS -----");
t1.showDetails();
System.out.println("\nSystem message: All data loaded successfully!");
}
}
Output:
----- SCHOOL INTRODUCTIONS -----
I'm Riya, a student of grade 10th Grade.
I'm Mr. Sharma, a teacher of Mathematics.
----- STUDENT DETAILS -----
Roll Number: 102
Age: 15
Grade: 10th Grade
----- TEACHER DETAILS -----
Subject: Mathematics
Experience: 12 years
Age: 40
System message: All data loaded successfully!
- Write this code by yourself and understand the Java inheritance concept at an advanced level.