What is Multilevel Inheritance In Java?
In Java (and in other object-oriented languages) a class can get features from another class. This mechanism is known as inheritance.
- When multiple classes are involved and their parent-child relation is formed in a chained way then such formation is known as multi-level inheritance.
- In multilevel inheritance, a parent a class has a maximum of one direct child class only.
- In multi-level inheritance, the inheritance linkage is formed in a linear way and minimum 3 classes are involved.
Code re-usability can be extended with multi-level inheritance.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class A { } class B extends A { } class C extends B { } |
Suppose, we have a form as shown above (class A is the parent of class B and class B is the parent of class C), then features of A are available for B, and features of B (including that of A) are available for C. So, class C get features of both A and B.
In this case, class B is the parent to C and child to A. such classes are generally known as intermediate classes. When an object of class C is created, constructors of all the three classes will be executed.
Even though the control goes to the constructor of C first, the actual sequence of execution will be the constructor of A first, the constructor of B next and constructor of C at last.
The following example gives a bit more clarity on multi-level inheritance.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
class Person { Person() { System.out.println("Person constructor"); } void nationality() { System.out.println("Indian"); } void place() { System.out.println("Mumbai"); } } class Emp extends Person { Emp() { System.out.println("Emp constructor"); } void organization() { System.out.println("IBM"); } void place() { System.out.println("New York"); } } class Manager extends Emp { Manager() { System.out.println("Manager constructor"); } void subordinates() { System.out.println(12); } void place() { System.out.println("London"); } } class Check { public static void main(String arg[]) { Manager m=new Manager(); m.nationality(); m.organization(); m.subordinates(); m.place(); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Person constructor Emp constructor Manager constructor Indian IBM 12 London |
In the above example, as discussed above, the constructor of grandparent class (Person) is executed first, then parent class (Emp) and then that of child class (Manager).
Then the method nationality() of Person and the method organization() of Emp are accessed through Manager object as if they are own methods of Manager. Then the method subordinates() of Manager (its own) is called.
We can see the corresponding outputs here. At last, we have invoked the method place() which exists in all the three classes. Here, the method of Person is overridden in Emp and the same method is overridden again in Manager.
So the version in Manager got executed. Had that method been not overridden in Manager, then the invocation could have executed the Emp version.
- If we don’t want a parent class feature (method or variable) to be available outside the class then we can make it private.
- In that case, such feature will not be available to child class also.
- If we want to control the accessibility so that they a feature can be accessed in the current package but not from outside then we make the feature as default (normal).
In the above example, all the methods are normal (default). So they cannot be accessed from other packages. If we make a feature a protected, then they can be accessed anywhere in the current package and from child classes of other packages.
If we make a feature as public, then there is no restriction, such elements can be accessed from anywhere.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
class X { int i; X() { i=5; } } class Y extends X { int j; Y() { j=6; } } class Z extends Y { int k; Z() { k=7; } } class MultipleInheritanceExample { public static void main(String args[]) { X a=new X(); // class X consist one variable i Y b=new Y(); // class Y consist variables j, i(it came from parent class X) Z c=new Z(); //class Z consist variables k,j(class y), i(class X) System.out.println(a.i); // a-->i=5 System.out.println(b.i+b.j);// b--->i=5,j=6 System.out.println(c.i+c.j+c.k);// c-->i=5,j=6,k=7 } } |
Output:
1 2 3 |
5 11 18 |
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
class Sem1 { int m11,m12,m13,m14,avg1; Sem1() { m11=95; m12=93; m13=88; m14=90; avg1=(m11+m12+m13+m14)/4; } } class Sem2 extends Sem1 { int m21,m22,m23,m24,avg2; Sem2() { m21=89; m22=98; m23=97; m24=79; avg2=(m21+m22+m23+m24)/4; } } class Sem3 extends Sem2 { int m31,m32,m33,m34,avg3; Sem3() { m31=87; m32=78; m33=88; m34=96; avg3=(m31+m32+m33+m34)/4; } } class Sem4 extends Sem3 { int m41,m42,m43,m44,avg4; Sem4() { m41=79; m42=90; m43=77; m44=96;avg4=(m41+m42+m43+m44)/4; } int totatavg() { return (avg1+avg2+avg3+avg4)/4; } } class MultipleInheritanceExample2 { public static void main(String args[]) { Sem4 s4=new Sem4(); System.out.println("semester 1 avg"+s4.avg1); System.out.println("semester 2 avg"+s4.avg2); System.out.println("semester 3 avg"+s4.avg3); System.out.println("semester 4 avg"+s4.avg4); System.out.println("total average "+s4.totatavg()); } } |
Output:
1 2 3 4 5 |
semester 1 avg 91 semester 2 avg 90 semester 3 avg 87 semester 4 avg 85 total average 88 |
Through interfaces also, we can see multi-level inheritance.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
interface First { } interface Second extends First { } interface Third extends Second { } interface Fourth extends Third { } |
A similar thing can be achieved using abstract classes also.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
interface One { } abstract class Two implements One { } class Three extends Two { } |
Even though we can have any number of classes (abstract classes) involved in this sequence, a final class cannot be used as a parent class. So the following code is not valid.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class A { } final class B extends A { } class C extends B //as B is final it cannot be a parent class. { } |
Other formations of inheritance:
Single-level inheritance
When there are only 2 classes involved and one is the parent and another is the child, such inheritance is known as a simple inheritance (single-level inheritance).
Example:
1 2 3 4 5 6 7 8 9 10 11 |
Class A { } Class B extends A { } |
Hierarchical inheritance
When there are 3 or more classes involved and there is a common parent for 2 or more child classes, such relation is hierarchical inheritance.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class A { } class B extends A { } class C extends A { } |
Multiple-inheritance
When there are multiple parent classes for a child class, such inheritance is known as multiple inheritances. This kind of inheritance is not supported in Java with classes. When interfaces are involved we can see multiple-inheritance in Java.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
interface A { } interface B { } interface C extends A,B { } |