Unit: 8 Inheritance

By Haitomns G

Inheritance in Java

Inheritance can be defined as the process where one class acquires the properties (methods and fields) of another. With the use of inheritance the information is made manageable in a hierarchical order.

The class which inherits the properties of other is known as subclass (derived class, child class) and the class whose properties are inherited is known as superclass (base class, parent class).

extends Keyword

extends is the keyword used to inherit the properties of a class. Following is the syntax of extends keyword.

Syntax:

class Super {

…..

…..

}

class Sub extends Super {

…..

…..

}

Example:

class Animal {

    void eat() {

        System.out.println(“eating…”);

    }

}

class Dog extends Animal {

    void bark() {

        System.out.println(“barking…”);

    }

}

class TestInheritance {

    public static void main(String args[]) {

        Dog d = new Dog();

        d.bark();

        d.eat();

    }

}

Example 2:

class Super_class {

   int num = 20;

   // display method of superclass

   public void display() {

      System.out.println(“This is the display method of superclass”);

   }

}

public class Sub_class extends Super_class {

   int num = 10;

   // display method of sub class

   public void display() {

      System.out.println(“This is the display method of subclass”);

   }

   public void my_method() {

      // Instantiating subclass

      Sub_class sub = new Sub_class();

      // Invoking the display() method of sub class

      sub.display();

      // Invoking the display() method of superclass

      super.display();

      // printing the value of variable num of subclass

      System.out.println(“value of the variable named num in sub class:”+ sub.num);

      // printing the value of variable num of superclass

      System.out.println(“value of the variable named num in super class:”+ super.num);

   }

   public static void main(String args[]) {

      Sub_class obj = new Sub_class();

      obj.my_method();

   }

}


Types of Inheritance

image
Types of Inheritance

Super Keyword in Java

The super keyword in Java is a reference variable which is used to refer immediate parent class object.

Whenever you create the instance of subclass, an instance of parent class is created implicitly which is referred by super reference variable.

Usage of Java super Keyword

  • super can be used to refer immediate parent class instance variable.
  • super can be used to invoke immediate parent class method.
  • super() can be used to invoke immediate parent class constructor.

Using Super To Call Superclass Constructors

Here, Emp class inherits Person class so all the properties of Person will be inherited to Emp by default. To initialize all the property, we are using parent class constructor from child class. In such way, we are reusing the parent class constructor.

Example:

class Person {

    int id;

    String name;

    Person(int id, String name) {

        this.id = id;

        this.name = name;

    }

}

class Emp extends Person {

    float salary;

    Emp(int id, String name, float salary) {

        super(id, name);// reusing parent constructor

        this.salary = salary;

    }

    void display() {

        System.out.println(id + ” ” + name + ” ” + salary);

    }

}

class TestSuper5 {

    public static void main(String[] args) {

        Emp e1 = new Emp(1, “ankit”, 45000f);

        e1.display();

    }

}

Super Can Be Used To Invoke Parent Class Method

The super keyword can also be used to invoke parent class method. It should be used if subclass contains the same method as parent class. In other words, it is used if method is overridden.

class Animal {

    void eat() {

        System.out.println(“eating…”);

    }

}

class Dog extends Animal {

    void eat() {

        System.out.println(“eating bread…”);

    }

    void bark() {

        System.out.println(“barking…”);

    }

    void work() {

        super.eat();

        bark();

    }

}

class TestSuper2 {

    public static void main(String args[]) {

        Dog d = new Dog();

        d.work();

    }

}

Super Is Used To Refer Immediate Parent Class Instance Variable

We can use super keyword to access the data member or field of parent class. It is used if parent class and child class have same fields.

class Animal{ 

String color=”white”; 

class Dog extends Animal{ 

String color=”black”; 

void printColor(){ 

System.out.println(color);//prints color of Dog class 

System.out.println(super.color);//prints color of Animal class 

class TestSuper1{ 

public static void main(String args[]){ 

Dog d=new Dog(); 

d.printColor(); 

}} 

Multilevel Inheritance Hierarchy in Java

Inheritance involves an object acquiring the properties and behaviour of another object. So basically, using inheritance can extend the functionality of the class by creating a new class that builds on the previous class by inheriting it.

Multilevel inheritance is when a class inherits a class which inherits another class. An example of this is class C inherits class B and class B in turn inherits class A.

A program that demonstrates a multilevel inheritance hierarchy in Java is given as follows:

Example

 Live Demo

class A {

   void funcA() {

      System.out.println(“This is class A”);

   }

}

class B extends A {

   void funcB() {

      System.out.println(“This is class B”);

   }

}

class C extends B {

   void funcC() {

      System.out.println(“This is class C”);

   }

}

public class Demo {

   public static void main(String args[]) {

      C obj = new C();

      obj.funcA();

      obj.funcB();

      obj.funcC();

   }

}

Output

This is class A

This is class B

This is class C

When are Constructors called?

The constructor is called when an object of a class is created. It can be used to set initial values for object attributes.

In Java, a constructor is a block of codes similar to the method. It is called when an instance of the class is created.

  • When a class hierarchy is created, in what order are the constructors for the classes that make up the hierarchy executed? For example, given a subclass called B and a superclass called A, is A’s constructor executed before B’s, or vice versa? 
  • The answer is that in a class hierarchy, constructors complete their execution in order of derivation, from superclass to subclass. 
  • Further, since super( ) must be the first statement executed in a subclass’ constructor, this order is the same whether or not super( ) is used. If super( ) is not used, then the default or parameterless constructor of each superclass will be executed. The following program illustrates when constructors are executed:

Example;

class College  

    /* Constructor */ 

    College() 

    { 

        System.out.println(“College constructor executed”); 

    } 

class Department extends College  

    /* Constructor */ 

    Department() 

    { 

        System.out.println(“Department constructor executed”); 

    } 

class Student extends Department  

    /* Constructor */ 

    Student() 

    { 

    System.out.println(“Student constructor executed”); 

    } 

public class OrderofExecution2  

        /* Driver Code */ 

    public static void main(String ar[])  

    { 

        /* Create instance of Student class */ 

        System.out.println(“Order of constructor execution in Multilevel inheritance…”); 

        new Student();   

    } 

Output:

Order of constructor execution in Multilevel inheritance…

College constructor executed

Department constructor executed

Student constructor executed

Method Overriding

  • In a class hierarchy, when a method in a subclass has the same name and type signature as a method in its superclass, then the method in the subclass is said to override the method in the superclass. 
  • When an overridden method is called from within its subclass, it will always refer to the version of that method defined by the subclass. The version of the method defined by the superclass will be hidden.
  • The benefit of overriding is: ability to define a behavior that’s specific to the subclass type, which means a subclass can implement a parent class method based on its requirement.
  • In object-oriented terms, overriding means to override the functionality of an existing method.

Rules for Method Overriding

  • The argument list should be exactly the same as that of the overridden method.
  • The return type should be the same or a subtype of the return type declared in the original overridden method in the superclass.
  • The access level cannot be more restrictive than the overridden method’s access level. For example: If the superclass method is declared public then the overridding method in the sub class cannot be either private or protected.
  • Instance methods can be overridden only if they are inherited by the subclass.
  • A method declared final cannot be overridden.
  • A method declared static cannot be overridden but can be re-declared.
  • If a method cannot be inherited, then it cannot be overridden.
  • Constructors cannot be overridden.

Example:

class Vehicle {

    // defining a method

    void run() {

        System.out.println(“Vehicle is running”);

    }

}

// Creating a child class

class Bike2 extends Vehicle {

    // defining the same method as in the parent class

    void run() {

        System.out.println(“Bike is running safely”);

    }

    public static void main(String args[]) {

        Bike2 obj = new Bike2();// creating object

        obj.run();// calling method

    }

}

Example 2:

class Bank {

    int getRateOfInterest() {

        return 0;

    }

}

// Creating child classes.

class Nabil extends Bank {

    int getRateOfInterest() {

        return 8;

    }

}

class Sunrise extends Bank {

    int getRateOfInterest() {

        return 7;

    }

}

class NBL extends Bank {

    int getRateOfInterest() {

        return 9;

    }

}

// Test class to create objects and call the methods

class Test2 {

    public static void main(String args[]) {

        Nabil s = new Nabil();

        Sunrise i = new Sunrise();

        NBL a = new NBL();

        System.out.println(“Nabil Rate of Interest: ” + s.getRateOfInterest());

        System.out.println(“Sunrise Rate of Interest: ” + i.getRateOfInterest());

        System.out.println(“NBL Rate of Interest: ” + a.getRateOfInterest());

    }

}

Dynamic Method Dispatch or Runtime Polymorphism in Java

Runtime Polymorphism in Java is achieved by Method overriding in which a child class overrides a method in its parent. An overridden method is essentially hidden in the parent class, and is not invoked unless the child class uses the super keyword within the overriding method. This method call resolution happens at runtime and is termed as Dynamic method dispatch mechanism.

Dynamic method dispatch is a mechanism by which a call to an overridden method is resolved at runtime. This is how java implements runtime polymorphism. When an overridden method is called by a reference, java determines which version of that method to execute based on the type of object it refer to. In simple words the type of object which it referred determines which version of overridden method will be called.

Example

Let us look at an example.

class Animal {

   public void move() {

      System.out.println(“Animals can move”);

   }

}

class Dog extends Animal {

   public void move() {

      System.out.println(“Dogs can walk and run”);

   }

}

public class TestDog {

   public static void main(String args[]) {

      Animal a = new Animal(); // Animal reference and object

      Animal b = new Dog(); // Animal reference but Dog object

      a.move(); // runs the method in Animal class

      b.move(); // runs the method in Dog class

   }

}

This will produce the following result −

Output:

Animals can move

Dogs can walk and run

In the above example, you can see that even though b is a type of Animal it runs the move method in the Dog class. The reason for this is: In compile time, the check is made on the reference type. However, in the runtime, JVM figures out the object type and would run the method that belongs to that particular object.

Therefore, in the above example, the program will compile properly since Animal class has the method move. Then, at the runtime, it runs the method specific for that object.

Abstract class in Java

A class which is declared as abstract is known as an abstract class. It can have abstract and non-abstract methods. It needs to be extended and its method implemented. It cannot be instantiated.

Points to Remember

  • An abstract class must be declared with an abstract keyword.
  • It can have abstract and non-abstract methods.
  • It cannot be instantiated.
  • It can have constructors and static methods also.
  • It can have final methods which will force the subclass not to change the body of the method.

Example:

abstract class Shape {

    abstract void draw();

}

// In real scenario, implementation is provided by others i.e. unknown by end

// user

class Rectangle extends Shape {

    void draw() {

        System.out.println(“drawing rectangle”);

    }

}

class Circle1 extends Shape {

    void draw() {

        System.out.println(“drawing circle”);

    }

}

// In real scenario, method is called by programmer or user

class TestAbstraction1 {

    public static void main(String args[]) {

        Shape s = new Circle1();// In a real scenario, object is provided through method, e.g., getShape()

                                // method

        s.draw();

    }

}

Example 2:

abstract class Bank {

    abstract int getRateOfInterest();

}

class SBI extends Bank {

    int getRateOfInterest() {

        return 7;

    }

}

class PNB extends Bank {

    int getRateOfInterest() {

        return 8;

    }

}

class TestBank {

    public static void main(String args[]) {

        Bank b;

        b = new SBI();

        System.out.println(“Rate of Interest is: ” + b.getRateOfInterest() + ” %”);

        b = new PNB();

        System.out.println(“Rate of Interest is: ” + b.getRateOfInterest() + ” %”);

    }

}

Using final with inheritance

During inheritance, we must declare methods with the final keyword for which we are required to follow the same implementation throughout all the derived classes. Note that it is not necessary to declare final methods in the initial stage of inheritance(base class always). We can declare a final method in any subclass for which we want that if any other class extends this subclass, then it must follow the same implementation of the method as in that subclass.

Example:

// Java program to illustrate

// use of final with inheritance

// base class

abstract class Shape {

    private double width;

    private double height;

    // Shape class parameterized constructor

    public Shape(double width, double height) {

        this.width = width;

        this.height = height;

    }

    // getWidth method is declared as final

    // so any class extending

    // Shape can’t override it

    public final double getWidth() {

        return width;

    }

    // getHeight method is declared as final

    // so any class extending Shape

    // can not override it

    public final double getHeight() {

        return height;

    }

    // method getArea() declared abstract because

    // it upon its subclasses to provide

    // complete implementation

    abstract double getArea();

}

// derived class one

class Rectangle extends Shape {

    // Rectangle class parameterized constructor

    public Rectangle(double width, double height) {

        // calling Shape class constructor

        super(width, height);

    }

    // getArea method is overridden and declared

    // as final so any class extending

    // Rectangle can’t override it

    @Override

    final double getArea() {

        return this.getHeight() * this.getWidth();

    }

}

// derived class two

class Square extends Shape {

    // Square class parameterized constructor

    public Square(double side) {

        // calling Shape class constructor

        super(side, side);

    }

    // getArea method is overridden and declared as

    // final so any class extending

    // Square can’t override it

    @Override

    final double getArea() {

        return this.getHeight() * this.getWidth();

    }

}

// Driver class

public class Test {

    public static void main(String[] args) {

        // creating Rectangle object

        Shape s1 = new Rectangle(10, 20);

        // creating Square object

        Shape s2 = new Square(10);

        // getting width and height of s1

        System.out.println(“width of s1 : ” + s1.getWidth());

        System.out.println(“height of s1 : ” + s1.getHeight());

        // getting width and height of s2

        System.out.println(“width of s2 : ” + s2.getWidth());

        System.out.println(“height of s2 : ” + s2.getHeight());

        // getting area of s1

        System.out.println(“area of s1 : ” + s1.getArea());

        // getting area of s2

        System.out.println(“area of s2 : ” + s2.getArea());

    }

}

Object class in Java

The Object class is the parent class of all the classes in java by default. In other words, it is the topmost class of java.

The Object class is beneficial if you want to refer any object whose type you don’t know. Notice that parent class reference variable can refer the child class object, know as upcasting.

Let’s take an example, there is getObject() method that returns an object but it can be of any type like Employee,Student etc, we can use Object class reference to refer that object. For example:

Object obj=getObject(); //we don’t know what object will be returned from this method 

The Object class provides some common behaviors to all the objects such as object can be compared, object can be cloned, object can be notified etc.

  • There is one special class, Object, defined by Java. 
  • All other classes are subclasses of Object. That is, Object is a superclass of all other classes. 
  • This means that a reference variable of type Object can refer to an object of any other class. 
  • Also, since arrays are implemented as classes, a variable of type Object can also refer to any array.
  • The Object class provides some common behaviors to all the objects such as object can be compared, object can be cloned, object can be notified etc.
  • Object defines the following methods, which means that they are available in every object.
MethodDescription
public final Class getClass()returns the Class class object of this object. The Class class can further be used to get the metadata of this class.
public int hashCode()returns the hashcode number for this object.
public boolean equals(Object obj)compares the given object to this object.
protected Object clone() creates and returns the exact copy (clone) of this object.
public String toString()returns the string representation of this object.
public final void notify()wakes up single thread, waiting on this object’s monitor.
public final void notifyAll()wakes up all the threads, waiting on this object’s monitor.
public final void wait(long timeout)causes the current thread to wait for the specified milliseconds, until another thread notifies (invokes notify() or notifyAll() method).
public final void wait(long timeout,int nanos)causes the current thread to wait for the specified milliseconds and nanoseconds, until another thread notifies (invokes notify() or notifyAll() method).
public final void wait()causes the current thread to wait, until another thread notifies (invokes notify() or notifyAll() method).
protected void finalize()is invoked by the garbage collector before object is being garbage collected.

The methods getClass( ), notify( ), notifyAll( ), and wait( ) are declared as final. You may override the others. The equals( ) method compares two objects. It returns true if the objects are equal, and false otherwise. The precise definition of equality can vary, depending on the type of objects being compared. The toString( ) method returns a string that contains a description of the object on which it is called. Also, this method is automatically called when an object is output using println( ). Many classes override this method. Doing so allows them to tailor a description specifically for the types of objects that they create.

Also, Read

  1. Unit-1 Java’s Lineage
  2. Unit-3 Data types, Variables, and Array
  3. Unit-4 Operator
  4. Unit-5 Control Statements
  5. Unit-6 Introducing Classes
  6. Unit: 7 A Closer Look at Methods and Classes

Haitomns G. is a desktop, android, and web developer based in Nepal. He has worked on building several websites, apps, and softwares for clients and independent projects. He is experienced in C, C++, C#, Java, Python, SQL, HTML, CSS, PHP, and JavaScript.

Leave a Comment

Slide to prove you're not a bot/spammer *