top

Search

Java Tutorial

.

UpGrad

Java Tutorial

Inheritance in Java

Introduction

In the ever-evolving landscape of object-oriented programming, Java stands tall as one of the most popular and powerful programming languages. At the heart of Java's success lies the concept of inheritance, a fundamental building block that empowers developers to create efficient, reusable, and modular code.

In this comprehensive guide, we will embark on a journey to unravel the depths of inheritance in Java. We will explore the practical implementation of inheritance, different types of inheritance supported by Java, and the advantages and disadvantages associated with its usage. By the end of this guide, you will possess the knowledge and insights to wield inheritance as a powerful tool in your Java programming endeavors.

What is Inheritance in Java?

Inheritance in Java is a technique that allows new classes to be derived from existing classes, inheriting their properties, methods, and behaviors. By leveraging inheritance, developers can build upon the foundation laid by existing classes, saving time and effort while promoting code reusability and extensibility.

Why do we need inheritance in Java?

Inheritance is essential in Java for several reasons including:

  • Inheritance in Java encourages the reuse of code: It gains access to the attributes, methods and behaviors of parent classes, which enables developers to make use of existing code. Code reuse makes the development process simpler since redundant code does not need to be rewritten. 

  • Inheritance improves modularity and code organization: This is because related functionalities can be logically arranged into classes using a hierarchical framework. This makes it simpler to extend, maintain, and comprehend the code.

  • Polymorphism: It is an essential component of object-oriented programming. Through inheritance, items from many classes might be seen as belonging to a single superclass. This flexibility enables more generic and adaptable code, making maintenance and scaling simpler.

Access Modifiers in Java

The visibility and use of classes, variables, methods, and constructors are determined by access modifiers in Java. They are essential in regulating access to inherited members and influencing how inheritance behaves. In Java, there are 4 access modifiers:

  1. Public access modifiers:

The public access modifier allows unrestricted access to a class, its members, and inherited members. Public members can be accessed from anywhere within the program, including external classes and packages. 

  1. Private private access modifiers:

The private access modifier restricts access to the class itself. Private members are not accessible outside the class in which they are declared, including subclasses. Therefore, private members cannot be inherited or accessed by subclasses. They are primarily used for encapsulation and to ensure data integrity within the class.

  1. Protected:

Within the same package and subclasses, even if they are in distinct packages, the protected access modifier permits access to the class, its members, and inherited members. A level of accessibility between public and private is offered by protected members. They are frequently used when you wish to restrict access to some classes while allowing access to subclasses in various packages.

  1. Default (Package-private):

The default access modifier is applied when no access modifier is explicitly specified. It allows access to the class, its members, and inherited members within the same package. Default members are not accessible to classes in different packages. This access modifier is useful when you want to limit the visibility of members to the package in which they are defined.

The Super Keyword in Java

In Java, the super keyword is used to refer to the immediate parent class or superclass. It enables communication and interaction between a subclass and its superclass. It allows for the invocation of superclass constructors. It also gives access to superclass members and allows the overriding of superclass methods. 

class Superclass 
{ 
 int i =20; 
void display() 
{ 
 System.out.println(“Superclass display method”) ; 
 } 
} 
class Subclass extends Superclass 
{ 
 int i = 100; 
 void display() 
 { 
 super.display() ; 
 System.out.println(“Subclass display method”) ; 
 System.out.println(“ i value =”+i) ; 
 System.out.println(“superclass i value =”+super.i) ; 
 } 
} 
class SuperUse
{ 
 public static void main(String args[ ] ) 
{ 
 Subclass obj = new Subclass( ) ; 
 obj.display( ) ; 
} 
}

The super Keyword is used for the following purpose:

  • Invoking Superclass Constructors: By calling the super() statement within a subclass constructor, you can initialize the inherited members from the superclass. By doing this, the superclass's initialization logic is executed before the subclass's specific logic.

  • Accessing Members of Superclasses: The super keyword provides access to fields, methods, and nested classes that are members of superclasses. When a subclass wants to refer to or use a member that is overridden or concealed in the subclass itself, it is especially helpful. 

  • Overriding Superclass Methods: Java's super keyword can be used to call the superclass version of a method that has been overridden by a subclass when that method was inherited from the superclass. 

How to use Inheritance in Java

Here is a step-by-step guide to implementing inheritance in Java, especially if you are not an expert in the language.

  1. Establish a Superclass

You should create a superclass with shared attributes and methods for the subclasses as the initial step in this procedure. The superclass should then be given a suitable name before being declared using the class keyword. Attributes and methods from the superclass that you want the subclasses to inherit should be listed last.

  1. Create Subclasses

The superclass is then expanded to produce subclasses. Use the extends keyword and the superclass name to accomplish this. Give the subclass a name that fits at this point and define it with the keyword. As a result, all non-private properties and methods from the superclass will be inherited by the subclass.

  1. Customize the Subclasses

Take use of the opportunity to include new, subclass-specific characteristics and methods. You can override the inherited methods to give an alternative implementation that fits the particular requirements of the subclass. Declare a method with the same signature (name, return type, and parameters) in the subclass to override an existing one. If you want to make it clear that you're overriding the method on purpose, use the @Override annotation.

  1. Access Inherited Members

In the subclasses, you can directly access the inherited members (attributes and methods) from the superclass. You can use the dot notation (.) to access the superclass members because the public and private members of the superclass are accessible within the subclass.

  1.  Implement Custom Functionality

Here, you provide unique functionality using the extra attributes and methods in the subclasses. Use the inherited members from the superclass as a starting point and build upon them.

  1. Test the Inheritance Hierarchy

Lastly, create objects of the subclasses and then test the inherited and overridden functionality. You should also invoke and access attributes from both the superclass and subclass objects. The following example shows inheritance in java example:

// Java Program to illustrate Inheritance (concise)
  
import java.io.*;
  
// Base or Super Class
class Employee {
    int salary = 60000;
}
  
// Inherited or Sub Class
class Engineer extends Employee {
    int benefits = 10000;
}
  
// Driver Class
class Gfg {
    public static void main(String args[])
    {
        Engineer E1 = new Engineer();
        System.out.println("Salary : " + E1.salary
                           + "\nBenefits : " + E1.benefits);
    }
}

Types of Inheritance in Java

There are several types of inheritance in Java, including single inheritance, multiple inheritance (through interfaces), and hybrid inheritance.

  1. Single Inheritance in Java:

When a subclass extends a single superclass, this is referred to as single inheritance between two classes. The subclass inherits the superclass's attributes and methods under this type of inheritance. The following is the syntax for single inheritance:

  1. Multiple Inheritance in Java:

A class can derive from various interfaces thanks to multiple inheritance. In Java, an interface outlines a contract for classes to adhere to specific behaviors. A class can inherit the constants and methods defined in several interfaces by implementing them. 

  1. Hybrid Inheritance in Java:

Hybrid inheritance refers to a combination of single inheritance and multiple inheritance. It occurs when a class extends a superclass and implements multiple interfaces. This allows for the inheritance of attributes and methods from both the superclass and the interfaces.

  1. Multilevel Inheritance:

A derived class will inherit a base class in multilevel inheritance, and in addition, the derived class will serve as the base class for subsequent classes. In the illustration below, class A acts as the base class for class B, which in turn acts as the base class for class C. A class in Java cannot access the members of the grandparents directly.

  1. Hierarchical inheritance:

One class acts as the superclass (base class) for multiple subclasses in hierarchical inheritance. The base class for the derived classes B, C, and D in the figure below is class A.

Java IS-A Type of Relationship

In Java, inheritance is used to establish the IS-A relationship. It designates a subclass as a particular kind of its superclass. Designing a well-structured object-oriented system and exploiting inheritance efficiently require an understanding of the IS-A relationship. 

public class SolarSystem {
}
public class Earth extends SolarSystem {
}
public class Mars extends SolarSystem {
}
public class Moon extends Earth {
}

A class is a specialized form of another class when there is an IS-A relationship, which is a manner of expressing inheritance. A subclass inherits characteristics and actions from its superclass in a hierarchical connection between classes. The substitutability principle, which states that an object of the subclass can be used anywhere an object of the superclass is anticipated, is the foundation of the IS-A relationship.

Advantages of Inheritance in Java:

You may use inheritance effectively by understanding its benefits and using them to inform your design choices. The following are some benefits of using inheritance in Java:

  • Reusing code: By letting subclasses take on properties and functions from their superclass, inheritance encourages code reuse. 

  • Enhanced maintainability: Inheritance improves code maintainability by creating a distinct and organized class hierarchy. 

  • Modularity Enhancement: Software design can be modular thanks to inheritance. You can isolate functionality in different classes and concentrate on certain components by structuring your code into a hierarchy of related classes. 

  • Polymorphic Behavior: Inheritance enables polymorphism, which is a fundamental concept in object-oriented programming. Polymorphism allows objects of different subclasses to be treated as objects of their common superclass.

  • Extensibility and Flexibility: Inheritance provides a foundation for extensibility and flexibility in software design. 

  • Design Patterns: Inheritance is widely used in various design patterns such as the Template Method, Factory Method, and Strategy patterns. 

Disadvantages of Inheritance in Java:

Let's explore some of the common disadvantages of inheritance in Java:

  • Fragile Base Class Problem: The fragile base class problem occurs when modifications to the superclass can inadvertently break the functionality of its subclasses. 

  • Inflexible Class Hierarchy: Inheritance introduces a rigid class hierarchy, where subclasses are tightly coupled to their superclass. 

  • Limited Support for Multiple Inheritance: Java supports single inheritance, meaning a class can only inherit from a single superclass. 

  • Increased Complexity and Coupling: Inheritance can introduce complexity and coupling between classes. 

  • Overuse and Inheritance Hierarchy Pollution: Overuse of inheritance can lead to an overly complex and bloated inheritance hierarchy. 

  • Dependency on Superclass Implementation: Subclasses are dependent on the implementation details of their superclass.

  • Difficulty in Testing and Debugging: Inheritance can complicate testing and debugging processes. Inherited behavior and dependencies from the superclass may impact the testing and debugging of subclasses. 

Conclusion

In conclusion, inheritance in Java is a powerful mechanism that enables code organization, reusability, and extensibility. By understanding the concepts and considerations discussed in this guide, you can effectively leverage inheritance to create well-designed, modular, and maintainable Java applications. Embrace the wealth of possibilities that inheritance offers and cultivate it wisely to unlock the full potential of your Java programs.

FAQs:

1. What is the difference between 'extends' and 'implements' in Java inheritance?

In Java, 'extends' is used when one class inherits from another, enabling the reuse of fields and methods of the existing class. On the other hand, 'implements' is used when a class wants to adhere to a certain interface, meaning it must implement all methods declared in the interface.

2. What is polymorphism in Java?

Polymorphism in Java refers to the ability of an object to take on many forms. It allows objects of different classes to be treated as objects of a common superclass or interface. Polymorphism enables dynamic method binding and promotes code flexibility and reusability.

3. What is an example of inheritance?

An example of inheritance in Java is the relationship between a superclass "Vehicle" and its subclass "Car". The "Vehicle" class may have common attributes and methods for all vehicles, such as "startEngine()" and "stopEngine()". The "Car" class, as a subclass, can inherit these attributes and methods from the "Vehicle" class while also having its own unique attributes and methods specific to cars. The "Car" class extends or overrides the common functionality of a vehicle as necessary through inheritance.

Leave a Reply

Your email address will not be published. Required fields are marked *