Inheritance Training In Java (In Quite Simple Language)
Inheritance is one of the main features of OOP (object-oriented programming) that allows us to define a new class from an existing class.
For example,
- class Animal
- {
- // eat () method
- // sleep () method
- }
- class Dog extends Animal
- {
- // bark () method
- }
In Java, we use the extends keyword to inherit a class. Here, the Dog class inherits from the Animal class.
Animal is a superclass (parent class or base class) and Dog is a subclass (child class or derivative class). The subclass inherits features and methods from the superclass.
It is important to note that only those members that are visible (available) are inherited by the subclass.
Is-a relationship
Inheritance is an is-a relationship. We use inheritance only if there is an is-a relationship between the two classes.
Here are some examples:
- The car is a vehicle.
- An orange is a fruit.
- The surgeon is a doctor.
- The dog is an animal.
Example 1: Inheritance in Java
- class Animal {
- public void eat () {
- System.out.println (“I can eat”);
- }
- public void sleep () {
- System.out.println (“I can sleep”);
- }
- }
- class Dog extends Animal {
- public void bark () {
- System.out.println (“I can bark”);
- }
- }
- class Main {
- public static void main (String [] args) {
- Dog dog1 = new Dog ();
- dog1.eat ();
- dog1.sleep ();
- dog1.bark ();
- }
- }
Output
I can eat
I can sleep
I can bark
Here, we inherited the Dog class from the Animal superclass. The Dog class inherits the eat () and sleep methods from the Animal class.
Hence, Dog class objects can invoke Dog class and Animal class methods.
Example 2: protected keyword
- class Animal {
- protected String type;
- private String color;
- public void eat () {
- System.out.println (“I can eat”);
- }
- public void sleep () {
- System.out.println (“I can sleep”);
- }
- public String getColor () {
- return color;
- }
- public void setColor (String col) {
- color = col;
- }
- }
- class Dog extends Animal {
- public void displayInfo (String c) {
- System.out.println (“I am a” + type);
- System.out.println (“My color is” + c);
- }
- public void bark () {
- System.out.println (“I can bark”);
- }
- }
- class Main {
- public static void main (String [] args) {
- Dog dog1 = new Dog ();
- dog1.eat ();
- dog1.sleep ();
- dog1.bark ();
- dog1.type = “mammal”;
- dog1.setColor (“black”);
- dog1.displayInfo (dog1.getColor ());
- }
- }
Output
I can eat
I can sleep
I can bark
I am a mammal
My color is black
In the example above, the Animal class has a color property that is private. Hence, it is only visible in Animal. Therefore, the Dog subclass cannot inherit it.
To access the color attribute, we used the general getColor () and setColor () methods inside the Animal superclass.
Also, pay attention to the protected keyword. protected is an access level regulator, just like public and private.
Protected members are also visible in a package and subclass. In the example above, the Animal superclass has a type attribute that is declared protected. Hence, the Dog subclass can access it.
Overriding method
From the above examples, we see that objects in a subclass can access superclass methods as well as define their own methods.
What happens if the same method is defined in both the superclass and the subclass?
Well, in this case, the methods in the subclass reject the methods in the superclass. For example,
Example 3: Example of the overriding method
- class Animal {
- protected String type = “animal”;
- public void eat () {
- System.out.println (“I can eat”);
- }
- public void sleep () {
- System.out.println (“I can sleep”);
- }
- }
- class Dog extends Animal {
- @Override
- public void eat () {
- System.out.println (“I eat dog food”);
- }
- public void bark () {
- System.out.println (“I can bark”);
- }
- }
- class Main {
- public static void main (String [] args) {
- Dog dog1 = new Dog ();
- dog1.eat ();
- dog1.sleep ();
- dog1.bark ();
- }
- }
Output
I eat dog food
I can sleep
I can bark
Here, the eat () method exists in both the Animal superclass and the Dog subclass. We created the dog1 object from the Dog subclass.
When we call the eat () method using the dog1 object, the method inside the Dog class is called and the superclass method is not called. This is called the overriding method.
In the above program, we used the overriding method to tell the compiler that we were overcoming the method. However, it is not mandatory.
If we need to call the eat () method of Animal from the Dog subclass, we use the super keyword.
Example 4: super keyword
- class Animal {
- public Animal () {
- System.out.println (“I am an Animal”);
- }
- public void eat () {
- System.out.println (“I can eat”);
- }
- }
- class Dog extends Animal {
- public Dog () {
- super ();
- System.out.println (“I am a dog”);
- }
- @Override
- public void eat () {
- super.eat ();
- System.out.println (“I eat dog food”);
- }
- public void bark () {
- System.out.println (“I can bark”);
- }
- }
- class Main {
- public static void main (String [] args) {
- Dog dog1 = new Dog ();
- dog1.eat ();
- dog1.bark ();
- }
- }
Output
I am an Animal
I am a dog
I can eat
I eat dog food
I can bark
Here, we have used the super keyword to call the constructor using super (). Also, using the super.eat () method, we used the Animal superclass eat () method.
When using the constructor and method, pay attention to the difference between using super.
Inheritance types
There are 5 types of inheritance:
- Single heirs – Class B inherits only from Class A.
- Multilevel Inheritance – Class B inherits from Class A, then Class C inherits from Class B.
- Hierarchical Inheritance – Class A acts as a superclass for classes B, C, and D.
- Multiple Inheritance – Class C inherits from interfaces A and B.
- Combined Inheritance – A combination of two or more types of inheritance.
Java does not support multiple and hybrid class inheritance. But it can be used with the help of interfaces.
Why do we use inheritance?
The most important application is the ability to reuse code. The code in the parent class does not need to be rewritten in the child class.
Another application is to use the overriding method so that runtime polymorphisms can be achieved.