Interface and Inheritance in Java: Inheritance

    Sandeep Panda
    Sandeep Panda
    Share

      When a class extends another class it’s called inheritance. The class that extends is called sub class while the class that is extended is called super class. Any class in java that does not extend any other class implicitly extends Object class. In other words every class in java directly or indirectly inherits Object class. By means of inheritance a class gets all the public, protected properties and methods of the super class no matter which package the sub class is present in. If the sub class is present in the same package as that of super class then it gets the package private properties and methods too. Once the sub class inherits the properties and methods of super class, it can treat them as if it defined them. By using inheritance you can reuse existing code. If you have an already written class (but no source) and it lacks some features then you don’t have to write everything from scratch. Just extend the class and add a new method that satisfies your needs. Note: Private methods and properties are not inherited. However, if the super class has a private variable and a public method that uses the variable then the variable is made available inside the method in the sub class. You should also note that constructors are never inherited.

    How to Extend

    Use extends keyword to inherit the super class-
    class A{
    
    //properties and methods of A
    
    }
    
    class B extends A {
    
    }
    Note: A class can inherit only one class. Multiple inheritance is not supported in Java.

    Method Overriding And Hiding

    When a sub class defines a method that has same signature and return type (or compatible with return type of super class method) it is called method overriding. Example:
    class A{
    
    int x;
    
    public void printIt(){
    
    System.out.println(“method in class A”);
    
    }
    
    }
    
    class B extends A{
    
    public void printIt(){
    
    System.out.println(“method in class B”);
    
    }
    
    }
    
    class Test{
    
    public static void main(String[] args){
    
    A a=new B();
    
    a.printIt(); // prints “method in class B” without quotes
    
    }
    
    }
    Here class B extends class A and overrides the method printIt(). So, when we run the above code the method that gets called is printIt() of class B. By overriding printIt()
    defined in class A, class B can provide a different implementation to it. Still it can access the super class version of the method by using super keyword. Example:
    class B extends A{
    
    public void printIt(){
    
    super.printIt();
    
    System.out.println(“method in class B”);
    
    }
    
    }
    Note: In the previous example we have used the reference of type A and object of B. But whose printIt() method will be called is not decided during compilation time. Java waits till the runtime of the program and checks which object the reference is pointing to. In this case the object is of class B. So, it’s B’s printIt()
    method which is getting executed. This is called dynamic method dispatch or virtual method invocation. Now let’s assume class A has a static method printStatic  and class B, which is a sub class of A, defines a static method having same signature as that of A’s printStatic. This is a case of method hiding
    . Example:
    class A{
    
    public static void printStatic(){
    
    System.out.println("In A");
    
    }}
    
    class B extends A{
    
    public static void printStatic(){
    
    System.out.println("In B");
    
    }
    
    }
    
    class Test{
    
    public static void main(String[] args){
    
    A a=new B();
    
    a.printStatic(); // prints “In A” without quotes
    
    //We can also call like this A.printStatic()
    
    }
    
    }
    In this case at compilation time Java will look for the reference type and not the object that is being pointed to. Here, the reference type is A. So, printStatic() of class A is executed.

    Casting Objects

    Let’s take the example where class A is super class and class B is the sub class. We already know that it is possible to create an object of class B and assign it to a reference of type A. But by doing this you will be able to call the methods that are defined in class A only. In order to call the methods that are defined by class B you need to cast the reference. Example:
    A a=new B();
    
    a.methodSpecificToB(); // illegal
    
    B b=(B)a;
    
    b.methodSpecificToB(); //legal

    Constructor Chaining

    When we instantiate a sub class the super class constructor also runs. It happens by means of a call to super(). When we don’t explicitly call super() inside a sub class constructor the compiler implicitly puts super() as the first statement in each of the overloaded constructors (like methods, constructors can also be overloaded) assuming that a call to this() is not present in the constructors. If you don’t define a constructor for your class the compiler creates a default constructor (which is no arg) and places a call to super()
    . The only condition is that your super class should have a no arg constructor or else it will produce a compile time error. If you have a super class that does not have a no arg constructor then you should call super() with appropriate parameters from your sub class constructor. The concept will be clear from the following example:
    class A{
    
    A(){
    
    System.out.println(“Constructor of A running”);
    
    }
    
    }
    
    class B extends A{
    
    B(){
    
    //a call to super() is placed here
    
    System.out.println(“Constructor of B running”);
    
    }
    
    }
    
    public class Test{
    
    public static void main(String[] args){
    
    new B();
    
    }
    
    }

    Output

    Constructor of A running Constructor of B running Note: The sub class constructor is called first, but it’s the super class constructor that finishes executing first.

    Summary

    • A class can extend only one class.
    • Every class is a sub class of Object directly or indirectly.
    • A super class reference can refer to a sub class object.
    • If reference is super class and object is of sub class then calling an instance method on it will result in execution of the method defined in sub class.
    • An overridden method has same signature and return type (or compatible with the return type) as that of super class method.
    • We can hide a static method defined in super class by defining a static method having same signature or return type (or compatible with the return type) as that of super class method.
    • When a sub class constructor runs the super class constructor also runs. This is called constructor chaining.

    Frequently Asked Questions (FAQs) about Interface and Inheritance in Java

    What is the difference between interface and inheritance in Java?

    In Java, an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. It provides a way to ensure that a class adheres to a certain contract without having to define how these methods are implemented. On the other hand, inheritance is a mechanism where one class acquires the properties (fields) and behaviors (methods) of another class. The class which inherits the properties of another class is known as a subclass, and the class whose properties are inherited is known as a superclass.

    Can a class extend multiple classes in Java?

    No, a class in Java cannot extend multiple classes. Java does not support multiple inheritance with classes. In other words, you can only extend one class in Java. However, a class can implement multiple interfaces, which is Java’s way of allowing a form of multiple inheritance.

    How does the ‘super’ keyword work in Java inheritance?

    The ‘super’ keyword in Java is a reference variable that is used to refer to the immediate parent class object. It can be used to invoke the immediate parent class method, to invoke the immediate parent class constructor, and to refer to the immediate parent class instance variable. It is commonly used in the methods of a subclass to call a method or constructor defined in its superclass.

    What is the purpose of interfaces in Java?

    Interfaces in Java are used to achieve abstraction and multiple inheritance. They provide a way to ensure that a class adheres to a certain contract without having to define how these methods are implemented. This means that when a class implements an interface, it inherits the abstract methods of the interface. This allows Java to support the concept of multiple inheritance.

    What is method overriding in Java inheritance?

    Method overriding in Java is a feature that allows a subclass to provide a specific implementation of a method that is already provided by its superclass. It is used when a class wants to specify a behavior that’s specific to that class, even though a method with the same name is already defined in its superclass. The method in the subclass must have the same name, return type, and parameters as the one in its superclass.

    Can we override static methods in Java?

    No, we cannot override static methods in Java. While you can declare a method with the same name in a subclass, it does not override the superclass’s method. The method in the subclass is a completely different method, separate from the one in the superclass.

    What is the ‘final’ keyword in Java inheritance?

    The ‘final’ keyword in Java is used to restrict the user. When a class is declared as final, it cannot be subclassed. This means that no other class can extend a final class. Similarly, when a method is declared as final, it cannot be overridden by subclasses. And when a variable is declared as final, its value cannot be changed once it has been initialized.

    What is the difference between ‘extends’ and ‘implements’ keywords in Java?

    The ‘extends’ keyword in Java is used for inheriting the features of a class or an interface. When a class extends another class, it inherits all of its fields and methods. On the other hand, the ‘implements’ keyword is used when a class wants to use an interface. When a class implements an interface, it needs to provide the implementation for all of its methods.

    What is multiple inheritance and why doesn’t Java support it?

    Multiple inheritance is a feature in which a class can inherit properties and methods from more than one superclass. However, Java does not support multiple inheritance with classes to avoid the “diamond problem”, where a class would inherit from two superclasses that have a common superclass, leading to ambiguity about which superclass method to use. Instead, Java supports multiple inheritance through interfaces.

    What is polymorphism in Java?

    Polymorphism in Java is a concept by which we can perform a single action in different ways. It allows us to define one interface and have multiple implementations. We can create functions or reference variables which behave differently in different programmatic context. There are two types of polymorphism in Java: compile-time polymorphism (method overloading) and runtime polymorphism (method overriding).