Java Tutorials – Inheritance

Hello, people…! In this post, we will explore the next part of object oriented programming in Java which is Inheritance.

Inheritance

Inheritance is a feature of object oriented programming which allows a class to be created from an existing class. More formally, inheritance is the process by which the new child subclass automatically includes any public or protected primitives, objects or methods defined in the parent class.
Let us see what is means. In Java, we implement inheritance by using the extends keyword at the time of class declaration. Go through the cod snippet below carefully –

class ParentClass {
    int var;
}

class ChildClass extends ParentClass {
    // empty
}

public class InheritanceDemo {

    public static void main(String[] args) {
        ParentClass parent = new ParentClass();
        ChildClass child = new ChildClass();

        System.out.println(parent.var);
        System.out.println(child.var);
    }

}

Important things to note are –

  • ChildClass inherits ParentClass using the keyword extends.
  • When ChildClass inherits the ParentClass, all the public/protected/default methods and variables are automatically available to the ChildClass.

So, when a ChildClass inherits (or extends) a ParentClass it gets a few resources from the ParentClass. Now let us see exactly what get’s inherited and what does not.

What is inherited?

  • public or default variables.
  • public or default methods.
  • abstract methods (remember abstract methods cannot be private).
  • public or default static methods.

What is not inherited?

  • constructors are not inherited.
  • private variables.
  • private methods.
  • private static methods.

this reference

Let’s say you have a class like this –

class Point {
    int x, y, z;

    public Point(int xValue, int yValue, int zValue) {
        x = xValue;
        y = yValue;
        z = zValue;
    }
}

Now, the constructor’s formal parameter names are descriptive, but a little redundant. In some cases, we would want the name of the formal parameter (xValue) to be same as that of the instance variable (x). What would happen if we did this?

class Point {
    int x, y, z;

    public Point(int x, int y, int z) {
        x = x;  // Assignment to itself
        y = y;
        z = z;
    }
}

It is of no use because the x inside the method is the formal parameter but not the instance variable of Point class. This happens because a local variable takes precedence over a global variable. So, how do we reference the instance variables where the formal parameters have the same name? We use this keyword! Take a look at the constructor below –

class Point {
    int x, y, z;

    public Point(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

We use this reference to refer to the instance variables, or, more formally, this reference is used to refer to the current instance. By current instance we imply the instance variables and methods. So, in the above code snippet, the instance variables are initialized to the formal parameters of the constructor.

So now that you know what this reference can you guess the output of the following code snippets?

Code SnippetSnippet Output
class Point {
    int x, y, z;

    public Point(int x, int y, int z) {
        x = x;
        this.y = y;
        z = this.z;
    }
}

class InheritanceDemo {

    public static void main(String[] args) {
        Point p = new Point(10, 20, 30);

        System.out.println(p.x);
        System.out.println(p.y);
        System.out.println(p.z);
    }

}
0
20
0

I hope you got the answer right! Let us look at the three statements in the constructor. The first statement assigns the formal parameter x to itself. The second statement is the right way of initializing, and hence y outputs 20. The third statement assigns the instance variable z (value is 0 currently) to the formal parameter z (value changed from 30 to 0).

super reference

Let’s say we have two classes, Doctor and ExpertDoctor. A Doctor works on a few things only whereas an ExpertDoctor does a little more than what a Doctor can do. The classes may look like –

class Doctor {
    public void work() {
        System.out.println("Check blood pressure");
        System.out.println("Check haemoglobin levels");
        System.out.println("Check glucose levels");
    }
}

class ExpertDoctor extends Doctor {
    public void work() {
        System.out.println("Check blood pressure");
        System.out.println("Check haemoglobin levels");
        System.out.println("Check glucose levels");
        System.out.println("Check liver functioning");
        System.out.println("Check heart functioning");
    }
}

Well, an ExpertDoctor IS A Doctor, so ExpertDoctor inherits Doctor class. But clearly, we are not getting any advantage here. The work() in ExpertDoctor does a little more than work() in Doctor. Wouldn’t it be nice if we could call work() method of Doctor class inside ExpertDoctor class? Then we would have to write only the additional work done by the ExpertDoctor. This can be achieved by using super reference!

class Doctor {
    public void work() {
        System.out.println("Check blood pressure");
        System.out.println("Check haemoglobin levels");
        System.out.println("Check glucose levels");
    }
}

class ExpertDoctor extends Doctor {
    public void work() {
        super.work();
        System.out.println("Check liver functioning");
        System.out.println("Check heart functioning");
    }
}

class InheritanceDemo {

    public static void main(String[] args) {
        ExpertDoctor doc = new ExpertDoctor();

        doc.work();
    }

}

So, we call work() method of Doctor class using super keyword. The output for the above code is –

Check blood pressure
Check haemoglobin levels
Check glucose levels
Check liver functioning
Check heart functioning

super is a keyword used to reference a member defined in the parent class and can be used throughout the child class.

this() constructor call

Can constructors be overloaded? Yes! You can have multiple overloaded versions of a constructor. Example –

class Time {
    int seconds, minutes, hours;
    
    // Contstructor 1
    public Time(int seconds) {
        this.seconds = seconds;
    }
    
    // Constructor 2
    public Time(int seconds, int minutes) {
        this(seconds); // Calls constructor 1
        this.minutes = minutes;
    }
    
    // Constructor 3
    public Time(int seconds, int minutes, int hours) {
        this(seconds, minutes); // Calls constructor 2
        this.hours = hours;
    }
}

In the above example, we several constructors each of which initialize a certain set of instance variables. We can use this() to call a constructor from another constructor.

super() constructor call

Similar to this(), Java has super(). It is used to call the parent class constructor. Example –

class Time {
    int seconds, minutes, hours;
    
    // Constructor 1
    public Time(int seconds) {
        this.seconds = seconds;
    }
    
    // Constructor 2
    public Time(int seconds, int minutes) {
        this(seconds); // Calls constructor 1
        this.minutes = minutes;
    }
    
    // Constructor 3
    public Time(int seconds, int minutes, int hours) {
        this(seconds, minutes); // Calls constructor 2
        this.hours = hours;
    }
}

class Date extends Time {
    int day, month, year;
    
    // Constructor 4
    public Date(int seconds, int minutes, int hours, int day) {
        super(seconds, minutes, hours); // Calls constructor 3
        this.day = day;
    }
    
    public Date(int seconds, int minutes, int hours, int day, int month, int year) {
        this(seconds, minutes, hours, day); // Calls constructor 4
        this.month = month;
        this.year = year;
    }
}

Rules about constructors –

  • The first line of the constructor must be a call to another constructor of the same class, or a call to the constructor of parent class.
  • If you don’t make a constructor call in the first line, Java automatically adds super() to the first line. So, if there’s no constructor in super class that matches to super(), a compilation error occurs.
  • If you don’t want Java to add a super() automatically in the first line, you must write your own constructor call explicitly.

I hope my post gave you a fair understanding of what inheritance is. If you have any doubts, feel free to comment them! Keep practicing! Happy Coding!! 😀