Monday, August 9, 2021

What is Inheritance in Java and OOP Tutorial - Example

Inheritance in Java is an Object oriented or  OOPS concepts, which allows to emulate real world Inheritance behavior, Inheritance allows code reuse in Object oriented programming language e.g. Java. Along with Abstraction, Polymorphism and Encapsulation, Inheritance forms basis of Object-oriented programming. Inheritance is implemented using extends keyword in Java and When one Class extends another Class it inherit all non private members including fields and methods. Inheritance in Java can be best understand in terms of Parent and Child class, also known as Super class and Sub class in Java programming language.


The class which extends another class becomes Child of the class it extends and inherits all its functionality which is not private or package-private given where Child class is created. 

Inheritance is the easiest way to reuse already written and tested code but not always the best way to do so, which we will see in this article. There are a lot of examples of Inheritance in Object-oriented world e.g. Child inherit properties from a parent, Dog inherit properties of Animal etc. 

In this Java and OOPS the tutorial we will learn What is Inheritance in Java, How to use Inheritance in Java, Simple Example of Java Inheritance and some important points about Inheritance in Java.


What is Inheritance in Java

What is Inheritance in Java with ExampleInheritance in Java is a way to define the relationship between two classes. Inheritance defines a Parent and Child relationship between two classes. Similar to real-world where a Child inherits his parent's Surname and other qualities.

In Java programming language, Child class inherit its Parent’s property and code. In Java programming, terms Super class and Sub Class is used to represent Parent and Child class, while in other object-oriented languages like C++, terms base and derived class is used to denote Inheritance

Inheritance is also the simplest but not the optimal way to reuse code and When one class use Inheritance to extend another class, it gets access to all non-private code written in Superclass. In the Context of Inheritance in Java, the following are legal :



1) Super class reference variable can point to Sub Class Object e.g.

SuperClass parent = new SubClass();

is legal at compile time because of IS-A relationship between Super class and Sub Class. In Java Sub Class IS-A Super class like Mango IS-A Fruit.

Similarly you can pass Sub class object in method arguments where Super class is expected, return Sub Class instance where return type of method is Super Class etc.

On the other hand if an you want to store object of Sub class, which is stored in super class reference variable, back on Sub class reference variable you need to use casting in Java, as shown below :

SubClass child = (SubClass) parent; //since parent variable pointing to SubClass object

This code will throw ClassCastException if parent reference variable doesn't point to a SubClass object.

Important points about Inheritance in Java

let’s see some worth noting points about Inheritance concepts in the Java programming language. These tips are very helpful while using the Inheritance in the Java program.

1) As I said earlier Inheritance in Java is supported using extends and implements keyword, extends keyword is used to inherit from another Java Class and allow to reuse functionality of Parent class. 

While implements keyword is used to implement Interface in Java. Implementing an interface in Java doesn't actually mean code reuse but provides Type hierarchy support. You can also use extends keyword when one interface extends another interface in Java.

2) If you do not want to allow Inheritance for your class than you can make it final.  final classes can not be extended in Java and any attempt to inherit final class will result in a compile-time error.

3) Constructor in Java are not inherited by Sub Class. In face Constructors are chained, first statement in constructor is always a call to another constructor, either implicitly or explicitly. If you don't call any other constructor compiler will insert super(), which calls no argument constructor of super class in Java. this keyword represents the current instance of a class and the super keyword represent an instance of super class in Java.

4) Inheritance in Java represents IS-A relationship. If you see IS-A relationship between your domain Objects and Classes than consider using Inheritance e.g. if you have a class called ProgrammingLanguage than Java IS-A ProgrammingLanguage and should inherit from ProgrammingLanguage class.

5) Private members of Super class is not visible to Sub class even after using Inheritance in Java. Private members include any private field or method in Java.

6) Java has a special access modifier known as protected which is meant to support Inheritance in Java. Any protected member including protected method and field are only accessible in Child class or Sub class outside the package on which they are declared.

7) One of the risks of Inheritance in Java is that derived class can alter the behavior of base class by overriding methods, which can compromise variants of the base class e.g. if a malicious class overrides String's equals method in Java to change the comparison logic, you may get different behavior when String reference variable points to that class. to prevent such malicious overriding, you can make your class final to disallow inheritance.

But beware making a class final severely implements its client's ability to reuse code. It make more sense from a security perspective and that's one of the reasons Why String is final in Java.

8) Use @Override annotation while overriding super class's method in subclass. This will ensure a compile-time check on whether the overriding method actually overrides super class method or not. Its a common mistake to overload a method instead of overriding it mostly when super class method accept Object type, common examples are equals method, compareTo method and compare() method in Java.



When to use Inheritance in Java

Many programmer says favor composition over Inheritance which is true but there are cases where Inheritance is a natural choice, Even in Java API there are many places where inheritances is used e.g. In Java collection framework most of concrete collection classes inherit from there Abstract counterpart e.g. HashSet extends AbstractSet , LinkedHashSet extends HashSet, ArrayList extends AbstractList etc. 

My general policy to decide whether to use Inheritance or not is to check "IS-A" relationship. For example, all above examples of Inheritance satisfy IS-A rule e.g. HashSet IS-A Set

Similarly if you have class called Fruit and want to create another class called Mango, its best to use inheritance and Mango should extend Fruit because Mango is a Fruit. By extending Fruit class it gets common state and behavior of Fruit object. 

Conversely if you find HAS-A relationship between two classes than use Composition e.g. Car HAS-A Seat, So Car class should be composed with a Seat and Seat should not extend Car here

Another general rule of Inheritance is that if you are creating a class which adds more feature into an existing class, you can extend it to reuse all of its code. That’s the reason of using  Runnable interface over Thread class for creating Thread in Java.


How to use Inheritance in Java

You can use Inheritance in Java by using two keywords, extends and implements. extends keyword is used when one Class inherit from other Class or one interface extend another interface. 

On the other hand implements keyword is used when a class implements an interface that is also a form of Abstraction in Java. Interestingly, Inheritance facilitate Polymorphism in Java. 

By using Inheritance Sub class gets all property of Superclass, except private,  and can represent Superclass i.e. you can store subclass instance in a Superclass reference variable, which is a form of Polymorphism in Java. All flexibility which is provided by interface based design is achieved using polymorphism. 

A common example of this Factory design pattern in Java where return type of Factory method should be base interface, which allows Factory method to return any implementation of base interface, which is actually created using Inheritance in Java. In next section we will an example of Inheritance, which will show How to code for inheritance.

Inheritance Example in Java

Here is a simple example of Inheritance in Java where we have a class called Server which represent any Server has common functionality e.g. uptime(), start() and stop(). Since every Server has own way of starting and stopping, it can override those method but any Server class can reuse common code which is applicable to all type of Server e.g. uptime.

/**
 *
 * Java program to demonstrate Inheritance in Java programming language.
 * Inheritance is used to reuse code and Java programming language allows you
 * to either extend class or implements Interface. In this Program we have a
 * Super Class Server and a Sub Class Tomcat, which is a Server.
 * Tomcat inherit start() and stop() method of Server Super Class.
 *
 * @author Javin
 */

public class Inheritance{

    public static void main(String args[]) {
        //Super class reference variable can hold Sub Class instance
        Server server = new Tomcat();
     
       //we need to cast to get actual Server instance back in reference variable.
       Tomcat tomcat = (Tomcat) server;     
       tomcat.start(); //starting Server
     
       System.out.println( "Uptime of Server in nano: " + server.uptime());
     
       tomcat.stop();
    }
 
 
}

class Server{
    private long uptime;
 
    public void start(){
        uptime = System.nanoTime();
    }
 
    public void stop(){
        uptime = 0;
    }
 
    public long uptime(){
        return uptime;
    }
}

class Tomcat extends Server{
 
    @Override
    public void start(){
        super.start();
        //Tomcat Server specific task
        System.out.println("Tomcat Server started");
    }
 
    @Override
    public void stop(){
        super.stop(); //you can call super class method using super keyword
        System.out.println("Tomcat Server Stopped");
    }
}

Output:
Tomcat Server started
Uptime of Server : 105898370823666
Tomcat Server Stopped


That’s all on What is Inheritance in Java, When to use Inheritance and How to use Inheritance in Java programming language. If you are coming from C++ background than only surprise for you is that Java does not support multiple Inheritance, other than that Java Inheritance is similar to Inheritance in any other programming language e.g. C++.


Related Java programming tutorial from Javarevisited Blog

6 comments:

  1. Hi,
    I have question regrading Hibernate "What is n+1 problem and what is the best feasible solutions to over come this problem"?
    can you please explain me and do the needful. thanks advance,

    ReplyDelete
  2. Thanks for the great post! I also did not know that Java does not support multiple inheritance like C++. This is a good reference which discusses that fact:


    http://www.programmerinterview.com/index.php/java-questions/multiple-inheritance/

    ReplyDelete
  3. But multiple inheritance still supports with Interfaces.


    http://codeinventions.blogspot.in/2014/07/can-interface-extend-multiple.html

    ReplyDelete
  4. Inheritance should not be used just for code reuse purpose, there are better ways to do that e.g. composition and delegation. Instead, you should only use Inheritance when substitution is possible. In another word Derived class take stand in place of Base class, this is also known as liskov subtituion principle. If you use Inhritance just for code reuse and your class voilate Liskov subtituion principle, then your API will not be clean and you will face several issues, when a derived class object is passed to a method expecting object of base class.

    ReplyDelete
  5. Java does support multiple inheritance, what it not support is multiple inheritance of state (which is bad). Java support multiple inheritance of type using interface and it's there from the beginning. From Java 8 onwards, Java has also started supporting multiple inheritance of behavior using default methods. So now, the question of whether Java supports multiple inheritance or not has become tricky to anser :-)

    ReplyDelete
  6. In your example there is kind of a mistake.
    "//we need to cast to get actual Server instance back in reference variable."
    that's not true because all methods in java are virtual. So even without casting to Tomcat it will call start and stop by the Tomcat instance.

    ReplyDelete