Main Inheritance Concepts
Overview
We saw why one might use inheritance here. In this post we'll build on that knowledge and see more concepts relating to inheritance.
Superclass, Subclass
I want to introduce two important terms used frequently when talking about inheritance: superclass
and subclass
.
Simply put if a class B extends class A than class B is subclass of class A and class A is superclass of class B. Sometimes the superclass is also called the parent
and subclass is also called the child
. See the following figure which is self-explanatory:
Now consider the following example:
As the image is self-explanatory, class B extends class A so class A is superclass of class B and class B is subclass of class A.
Now class C extends class B so class B is superclass of class C and class C is subclass of class B. Notice how class B is both subclass and superclass depending on in respect to which class we are talking.
Important Note: Inheritance can be looked at like transitive property in maths. If class B is subclass of class A and class C is subclass of class B, it automatically makes class C a subclass of class A
Types of Inheritance
We can inherit classes in different ways to create different types of inheritance.
Single Inheritance
Most basic type of inheritance. Class B extends Class A. Class B is subclass of Class A and Class A is superclass of Class B.
Multilevel Inheritance
We saw this example is the above section as well. This kind of inheritance is called multilevel inheritance.
Hierarchical Inheritance
When one class is extended by more than one subclasses, we call that Hierarchical Inheritance
Multiple Inheritance?
In multiple inheritance, one class extends two or more class. Did ya notice the question mark symbol in the heading? Why did I put it there. Let's look at the code of multiple inheritance to find some answers.
1class A {
2
3 public void func() {
4
5 System.out.println("Class A's func");
6 }
7}
1class B {
2
3 public void func() {
4
5 System.out.println("Class B's func");
6 }
7}
1class C extends A, B {
2
3
4}
1class HelperClass {
2
3 public static void main(String[] args) {
4
5 C c = new C();
6 c.func();
7 }
8}
Output:
1./C.java:1: error: '{' expected
2class C extends A, B {
3 ^
41 error
We made a class C and extended it from both A and B. While compiling this code we faced a compiler error as shown above. The reason behind this error is Java doesn't allow multiple inheritance. And the reason it doesn't allow this is actually straight-forward.
Notice that class A and class B both have an implementation of a method named func()
. Let's say Java allows multiple inheritance and let's us to compile this code. So now when we'll call func() method on C, Java has no way to know which version of func() to call, A's or B's because C is getting func() from both these parents. So to avoid this ambiguity Java doesn't allow multiple inheritance.
Inheritance of Instance Variables
Instance variables are also inherited from parent classes to child classes.
1class A {
2
3 public int a = 5;
4 public void func() {
5
6 System.out.println("Class A's func");
7 }
8}
1class B extends A {
2
3 public void func() {
4
5 System.out.println("Class B's func");
6 }
7}
1class HelperClass {
2
3 public static void main(String[] args) {
4
5 B b = new B();
6 System.out.println(b.a);
7 }
8}
Output:
15
You see in the above program class B extends class A and we are able to access 'a' instance variable using class B. This is because instance variables are also inherited. (You would've noticed that I used public identifiers to define instance variables in class A. I'll dive deep into other access modifiers in some later post)
A more Sophisticated Example
We'll code each and every class according to the UML diagram. Full code can be downloaded from here. I'll only show the helper class in this blog.
1class HelperClass {
2
3 public static void main(String[] args) {
4
5 Bicycle bicycle = new Bicycle();
6 System.out.println("Bicycle methods");
7 bicycle.makeNoise();
8 bicycle.lock();
9 bicycle.start();
10 bicycle.drive();
11
12 Scooter scooter = new Scooter();
13 System.out.println("Scooter methods");
14 scooter.makeNoise();
15 scooter.lock();
16 scooter.start();
17 scooter.drive();
18
19 SUV suv = new SUV();
20 System.out.println("SUV methods");
21 suv.makeNoise();
22 suv.lock();
23 suv.start();
24 suv.drive();
25
26 Sedan sedan = new Sedan();
27 System.out.println("Sedan methods");
28 sedan.makeNoise();
29 sedan.lock();
30 sedan.start();
31 sedan.drive();
32
33 Hatchbag hatchbag = new Hatchbag();
34 System.out.println("Hatchbag methods");
35 hatchbag.makeNoise();
36 hatchbag.lock();
37 hatchbag.start();
38 hatchbag.drive();
39
40 }
41}
Output:
1Bicycle methods
2Bicycle's makeNoise()
3Vehicle's lock()
4Bicycle's start()
5TwoWheeler's drive()
6Scooter methods
7Scooter's makeNoise()
8Vehicle's lock()
9Scooter's start()
10TwoWheeler's drive()
11SUV methods
12SUV's makeNoise()
13Vehicle's lock()
14SUV's start()
15FourWheeler's drive()
16Sedan methods
17Sedan's makeNoise()
18Vehicle's lock()
19Sedan's start()
20FourWheeler's drive()
21Hatchbag methods
22Hatchbag's makeNoise()
23Vehicle's lock()
24Hatchbag's start()
25FourWheeler's drive()
Focus on the following part of the inheritance and notice the relevant output.
When we call a method on Sedan, most specific version, i.e., version which is lowest in the inheritance tree is called.
Takeaways
- Superclass/subclass terminology
- Different types of inheritance
- Why Java doesn't allow multiple inheritance
- Instance variables are also inherited
- Lowest in inheritance tree wins
Acknowledgements
- The class example is inspired from Head First Java