What is inheritance in Java?
In Java, a class can be derived from an existing class and when that happens, the derived class inherits the fields and the methods from that existing class. In Java, and many other languages, this is called inheritance. The class that is derived from an existing class is often referred to as the subclass or child class. The class that is being derived from is called the super class or the parent class.
Consider a simple inheritance digram below.
Since Class B is inheriting from Class A, Class B is therefore the subclass of Class A and Class A is the superclass to Class B. Class B will inherit all fields and methods that Class A has.
Now, let’s implement a simple, introductory example. Let’s suppose we have a User class that has variables id and userName, and two simple methods sayHello() and sayGoodbye().
Now, what if our application will have different types of users. The standard user and a paid, premium user. We need to create a class that defines the premium user. We have two options to do so; we can do something like this:
This is a completely functional premium user class. However, as programmers we always want to abide by the DRY (Do not Repeat Yourself) principle and one of the ways to do that is through inheritance. Now, a better way to define a premium class would be like this:
This class has all the same functionality as the PremiumUser class in Fig. 2.2; the only difference is that we avoid repeating ourselves and our code looks a lot cleaner and is easier to read. The only different between our User and PremiumUser classes is the premiumId which only a premium user has.
This is the main advantage of using inheritance; the re-usability and extendibility of existing code. Using the extends keyword in the class declaration, our PremiumClass inherits all the fields and methods of the User class.
You may be wondering what the super(name, id) in the code above is all about!
The super keyword in Java is a reference variable that is used to refer to the immediate parent class (or superclass). It has two purposes; the first use case:
- it is used to invoke the superclass constructor from subclass
In Fig. 2.3, we used the super keyword to invoke the constructor from our parent class User, on our name and id variables; it allows us to re-use the entire constructor from our parent class with one line of code: super(name, id).
The second usage of the super keyword is that it allows us to:
- to differentiate the members of superclass from the members of subclass, if they have same names.
Consider the following code:
As you can see above, the method sayHello() exists in both our User (parent class) and in the PremiumUser (child class). However, in our program, when a PremiumUser says hello, they also ask “How are you?” so we extended the functionality of the sayHello() method that was inherited from the User class.
If we then run this code…
The output in the console will be:
How are you?
The super.sayHello() is responsible for the “Hello!”, which is inherited from the User class. In a nutshell, the super keyword allows you to extend the behaviour of the methods inherited from the super class.
Let’s say that instead of extending the behaviour of a method that’s inherited from the the parent class, you wanted to completely changed it. This is where the Override annotation comes into play. Here’s an example:
Both the User class and our PremiumUser have a method sayHello(). However, instead of saying “Hello” premium users says “What’s up?!”; this is done by overriding the method from the superclass. Having a method with the same name in our subclass, PremiumClass (and not using the super keyword), we are essentially over-writing the behaviour of our sayHello() method in the parent class. Hence, when we run our main program:
The output in the console will be:
One thing to note; override is an optional annotation that’s used to override (hide the method in your parent class) a method in Java. It is completely optional to use, it is a good practice to do so. Here’s why:
So, you are overriding a method and do not use this annotation; if you have spelling error and do not spell the name of the method you are overriding correctly, it will not inherit the parent method. Instead, you will have created a new method and there will be no warning of any kind. This can lead to unexpected behaviour since you are expecting your method to inherit an existing one but it does not.
However, if you do use this method and do not properly spell the name, you will receive a warning that you are not inhering any method.
So to save yourself a potential headache, always use the @Overrride annotation. It will prevent unwanted behaviour and make your code easier to read.
Hope you learned something ! :)