Inheritance in Java [Detailed Explanation]

Inheritance in Java [Detailed Explanation]

In this article, we'll learn and discuss about the Inheritance property along with their detailed approach using Java. Let's start!

Inheritance is a mechanism in object-oriented programming (OOP) that allows a new class to inherit the properties and methods of an existing class. The existing class is known as the parent class, or superclass, and the new class is known as the child class, or subclass. The child class inherits all the members (fields, methods, and nested classes) from the parent class and can add new members or override existing members to provide its own implementation. This allows for code reusability and improves organization of the codebase.

Why do we use Inheritance in Java?

Inheritance is used in Java for several reasons:

  1. Code Reusability: By inheriting from an existing class, a new class can reuse the code and functionality of the parent class, which can save development time and reduce the amount of code that needs to be written.

  2. Method Overriding: A child class can override the methods of the parent class to provide its own implementation, which allows for a more flexible and dynamic program.

  3. Method Overloading: A child class can overload the methods of the parent class, which allows for different behavior depending on the input parameters.

  4. Method Hiding: A child class can hide the methods of the parent class, which allows for a more encapsulated and secure program.

  5. Polymorphism: Inheritance allows for polymorphism, which is the ability of a single object to take on multiple forms. This allows for a more dynamic and flexible program.

  6. Code Organization: Inheritance allows for a more organized and structured codebase, as related classes can be grouped together based on their inheritance hierarchy.

  7. Improved Design: Inheritance allows for a more modular and extensible design, as new functionality can be added to a program by creating new subclasses that inherit from existing classes.

Syntax of Java Inheritance

The syntax for inheritance in Java is as follows:

  1. To create a subclass, you use the keyword "extends" after the name of the subclass and the name of the parent class.
class ChildClass extends ParentClass {
    // Fields and methods of the child class
}
  1. To access members of the parent class from the child class, you can use the keyword "super".
class ChildClass extends ParentClass {
    // Fields and methods of the child class
    public void someMethod() {
        super.parentMethod(); // calls the parentMethod() of the ParentClass
    }
}
  1. To override a method of the parent class in the child class, you use the keyword "override" before the method declaration.
class ChildClass extends ParentClass {
    @Override
    public void someMethod() {
        // new implementation of the someMethod()
    }
}

It is worth noting that when overriding a method, the overriding method should have the same method signature (i.e. same name, same return type and same parameter types) as the overridden method, otherwise, it will result in a compile-time error.

Also, Java only allows single inheritance, meaning a class can only extend one parent class. Though, it allows multiple interfaces implementation.

Java Inheritance Example

Here is an example of inheritance in Java:

class ParentClass {
    public int x;
    public void parentMethod() {
        System.out.println("This is a method from the parent class.");
    }
}

class ChildClass extends ParentClass {
    public int y;
    public void childMethod() {
        System.out.println("This is a method from the child class.");
    }
    @Override
    public void parentMethod() {
        System.out.println("This is an overridden method from the child class.");
    }
}

public class Main {
    public static void main(String[] args) {
        ChildClass child = new ChildClass();
        child.x = 10;
        child.y = 20;
        child.parentMethod();
        child.childMethod();
    }
}

In this example, the ChildClass is a subclass of the ParentClass. It inherits the field x and the method parentMethod() from the parent class. It also has its own field y and method childMethod(). The ChildClass overrides the parentMethod() from the parent class to provide its own implementation.

When we run the main method, it creates an object of ChildClass and assign values for x and y. Then it calls the parentMethod() and childMethod() of the child class.

The output of this program will be:

This is an overridden method from the child class.
This is a method from the child class.

This example demonstrates how the Child class can inherit the fields and methods from the Parent class, and also how it can override the methods of the Parent class to provide its own implementation.

Types of Inheritance

Single Inheritance

A class that inherits from only one parent class is known as single inheritance. Java is an example of a language that supports single inheritance.

Here is an example of single inheritance in Java:

class Parent {
    public int x;
    public void parentMethod() {
        System.out.println("This is a method from the parent class.");
    }
}

class Child extends Parent {
    public int y;
    public void childMethod() {
        System.out.println("This is a method from the child class.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.x = 10;
        child.y = 20;
        child.parentMethod();
        child.childMethod();
    }
}

In this example, the Child class is a subclass of the Parent class. It inherits the field x and the method parentMethod() from the parent class. It also has its own field y and method childMethod().

The Child class uses the keyword extends to inherit from the Parent class.

When we run the main method, it creates an object of Child and assign values for x and y. Then it calls the parentMethod() and childMethod() of the child class.

The output of this program will be:

This is a method from the parent class.
This is a method from the child class.

This example demonstrates how the Child class can inherit the fields and methods from the Parent class, and also how it can have its own fields and methods.

Multi-level Inheritance

A class that inherits from a parent class, which in turn inherits from another parent class is known as multi-level inheritance. Java supports multi-level inheritance.

Here is an example of multi-level inheritance in Java:

class GrandParent {
    public int x;
    public void grandParentMethod() {
        System.out.println("This is a method from the grand parent class.");
    }
}

class Parent extends GrandParent {
    public int y;
    public void parentMethod() {
        System.out.println("This is a method from the parent class.");
    }
}

class Child extends Parent {
    public int z;
    public void childMethod() {
        System.out.println("This is a method from the child class.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.x = 10;
        child.y = 20;
        child.z = 30;
        child.grandParentMethod();
        child.parentMethod();
        child.childMethod();
    }
}

In this example, the Child class is a subclass of the Parent class, and the Parent class is a subclass of the GrandParent class.

The Child class inherits the fields x and y and the methods grandParentMethod() and parentMethod() from the GrandParent and Parent classes respectively. It also has its own field z and method childMethod().

The Parent class inherits the field x and the method grandParentMethod() from the GrandParent class. It also has its own field y and method parentMethod().

The Child class uses the keyword extends to inherit from the Parent class, and the Parent class uses the keyword extends to inherit from the GrandParent class.

When we run the main method, it creates an object of Child and assign values for x, y, z. Then it calls the grandParentMethod(), parentMethod() and childMethod() of the child class.

The output of this program will be:

This is a method from the grand parent class.
This is a method from the parent class.
This is a method from the child class.

This example demonstrates how the Child class can inherit the fields and methods from the Parent class and GrandParent class, and also how it can have its own fields and methods. Multi-level inheritance allows a class to inherit the properties and methods of a parent class and the properties and methods of the parent class's parent class.

Hierarchical Inheritance

When multiple classes inherit from a single class, it is known as hierarchical inheritance. Java supports hierarchical inheritance.

Here is an example of hierarchical inheritance in Java:

class Parent {
    public int x;
    public void parentMethod() {
        System.out.println("This is a method from the parent class.");
    }
}

class Child1 extends Parent {
    public int y;
    public void childMethod1() {
        System.out.println("This is a method from the child1 class.");
    }
}

class Child2 extends Parent {
    public int z;
    public void childMethod2() {
        System.out.println("This is a method from the child2 class.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child1 child1 = new Child1();
        child1.x = 10;
        child1.y = 20;
        child1.parentMethod();
        child1.childMethod1();

        Child2 child2 = new Child2();
        child2.x = 30;
        child2.z = 40;
        child2.parentMethod();
        child2.childMethod2();
    }
}

In this example, the Child1 and Child2 classes are subclasses of the Parent class. They both inherit the field x and the method parentMethod() from the parent class. They also have their own fields y and z and methods childMethod1() and childMethod2() respectively.

The Child1 and Child2 classes use the keyword extends to inherit from the Parent class.

When we run the main method, it creates an object of Child1 and Child2 and assign values for x, y and z. Then it calls the parentMethod() and childMethod1() or childMethod2() of the child class.

The output of this program will be:

This is a method from the parent class.
This is a method from the child1 class.
This is a method from the parent class.
This is a method from the child2 class.

This example demonstrates how multiple classes can hierarchically inherit from a single class, allowing for a more organized and structured codebase.

Why Multiple Inheritance is not supported in Java?

As mentioned before, Java does not support multiple inheritance directly, as a class can only extend one parent class. However, there are ways to achieve similar functionality using interfaces.

An interface is a collection of abstract methods (methods without a body) that a class can implement. A class can implement multiple interfaces, thus achieving a form of multiple inheritance.

Here is an example of how you can achieve similar functionality to multiple inheritance in Java using interfaces:

interface InterfaceA {
    public void methodA();
}

interface InterfaceB {
    public void methodB();
}

class Child implements InterfaceA, InterfaceB {
    public void methodA() {
        System.out.println("This is method A.");
    }
    public void methodB() {
        System.out.println("This is method B.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.methodA();
        child.methodB();
    }
}

In this example, the Child class implements two interfaces InterfaceA and InterfaceB. Each interface defines a method methodA() and methodB(). The Child class has to implement those methods, thus it has the functionality of both interfaces.

When we run the main method, it creates an object of Child and calls the methodA() and methodB() of the Child class.

The output of this program will be:

This is method A.
This is method B.

It is worth noting that, interfaces can also extend multiple interfaces, in that way, a class can inherit multiple interfaces with a single implementation.

This approach allows for a more flexible and dynamic program, but it can also make the code more complex, as the class has to implement all the methods defined in the interfaces.

Aggregation

Aggregation is a form of association in object-oriented programming (OOP) that describes a "has-a" relationship between two classes. It is a way to model a whole-part or container-content relationship, where one class (the whole or container) has an instance of another class (the part or content) as a member variable.

For example, a class "Department" may have an instance of the class "Employee" as a member variable, representing the relationship between a department and its employees. The "Department" class would be the container class and the "Employee" class would be the content class.

In aggregation, the container class does not own the content class and does not control its lifetime. The content class can exist independently of the container class and can be shared by multiple container classes. The aggregation relationship is often represented by a diamond shape in class diagrams, with the arrow pointing to the content class.

Here is an example of Aggregation in Java:

class Department {
    private String name;
    private Employee employee;
    public Department(String name, Employee employee) {
        this.name = name;
        this.employee = employee;
    }
    public String getName() {
        return name;
    }
    public Employee getEmployee() {
        return employee;
    }
}

class Employee {
    private String name;
    public Employee(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) {
        Employee employee = new Employee("John");
        Department department = new Department("IT", employee);
        System.out.println("Department: " + department.getName());
        System.out.println("Employee: " + department.getEmployee().getName());
    }
}

In this example, the Department class contains an instance of the Employee class as a member variable. The Department class does not own the Employee class, and the Employee class can exist independently of the Department class.

When we run the main method, it creates an object of Employee and Department and pass the employee object to the department object. Then it calls the getName() method of Department and Employee class.

The output of this program will be:

Department: IT
Employee: John

This example demonstrates how the Department class uses an instance of Employee class, which represents the aggregation relationship between those two classes.


More articles on similar topics,

  1. Introduction to the concepts of OOPs.

  2. Introduction to the concepts of Python programming language.

  3. Beauty and Simplicity of Recursion.

  4. Introduction to Cloud Computing.

  5. How to get started with Git and GitHub?

Did you find this article valuable?

Support Abhishek Sharma by becoming a sponsor. Any amount is appreciated!