Here is the table content of the article we will cover on this topic.
1. What is Inheritance in java?
2. Important terms about Inheritance in java?
3. How to use inheritance?
4. Types of Inheritance in Java?
5. Single Inheritance?
6. Multilevel Inheritance?
7. Hierarchical Inheritance?
8. Interface inheritance in java?
9. How to extend multiple interfaces in java?
10. Multiple inheritances using the interface in java?
11. Type Casting in Inheritance?
12. Inheritance and method overriding?
13. What is Method overriding with inheritance?
14. Rules of method overriding in inheritance?
15. Difference between inheritance and composition?
16. What is Multiple inheritance in java?
17. What Problem occurs in multiple inheritance in Java?
18. How to achieve multiple inheritances?
19. What is the diamond problem in java?
20. How to resolve the diamond problem in java 8?
What is inheritance in Java?
Inheritance is an important concept/feature of Object-Oriented Programming. Inheritance is a mechanism by which one class can acquire/inherit the features(fields and methods) of another class. In this article, we will read about the concept of Inheritance in java. When one class inherits the variables and methods of another class. It is also known as the Is-A relationship.
- Reusability: The aim of inheritance is to reusability of code. If we want to create a new class but there is already a class that includes some of the code that we want, We can reuse the existing one by using the inheritance concept. We will discuss it in detail.
- Method Overriding: We will discuss it in polymorphism.
Important terms about Inheritance in java
Base/Super/Parent class: The Base class is the class whose variables and methods are used(inherited) by another class. It is also known as the superclass or parent class.
Derived/sub/child class: The Derived class is the class that inherits the variables or methods of other classes. It is also known as the subclass or child class. The derived class can add its own variables or methods in addition to the base class variables or methods
class Derived_Class_Name extends Base_Class_Name { // Body of derived class }
We can inherit the features of one class to another class by the use of keyword extends. The extends keyword tells the compiler to inherit the variables and methods of the Base class.
class ExampleOfBaseClass { // Body of base class } class ExampleOfDerivedClass extends ExampleOfBaseClass { // Body of derived class }
How to use inheritance in java?
Now I am going to show an example of inheritance. Let’s say we have a derived class, Swift that extends the base class, Car.
class Car { String nameOfCompany = "Suzuki"; boolean isACAvail = true; int numberOfTyre = 4; public void getCarDetails() { System.out.println("Company name of Car = "+ nameOfCompany); System.out.println("Is AC available in car = "+ isACAvail); System.out.println("Number tyres in Car = "+ numberOfTyre); } } public class Swift extends Car { String carName = "Swift"; String modelName = "Vxi"; String color = "white"; public void getModelDetails() { System.out.println("Name of Car = "+ carName); System.out.println("Model name = "+ modelName); System.out.println("Color of model = "+ color); } public static void main(String arg[]) { Swift newSwift = new Swift(); newSwift.getCarDetails(); newSwift.getModelDetails(); } }
Output: Company name of Car = Suzuki
Is AC available in car = true
Number tyres in Car = 4
Name of Car = Swift
Model name = Vxi
Color of model = white
As you see in the above example the swift class (Derived class) inherits the properties of the Car class (Base class). When we extend the Car class (Base class) then indirectly its code is available in the Swift class (derived class). So, we can easily access the variables or methods of a Car class (Base class).
How it relates to real life?
If you are the owner of a Car company and want to build a new model of car. Then you don’t want to build an engine, tire, body, etc. because these things are already discovered. In fact, these are the common things to build a car. So, you can use the existing things to build a car and add some new features according to your model.
In JAVA programming: Let’s define some common things in the Car class like company name, tire, etc. These are the generic things that are used to build any model of car. So, here we are declaring some variables and methods in class Car. Now, We can create a new class that will extend the Car class. In the below image, you can see we are inheriting the feature of one class to another.
Types of Inheritance in Java
- Single inheritance
- Multilevel inheritance
- Hierarchical inheritance
1. Single inheritance in java
In single inheritance, there is only one base class, and another is a derived class. The derived class inherits all the properties of the base class. The given above example is a type of single inheritance.
2. Multilevel inheritance in java
In multilevel inheritance, a derived class inherits the properties of a base class, and as well as the derived class also acts as a base class for other classes.
In this example, class B inherits the properties of class A, class C inherits the properties of class B. So, class B is acting as a derived class for class A and the base class for class C.
Example: In this example, we have three classes. Car is the base class, SwiftNew is the intermediate class and SwiftNewModel is the derived class. The SwiftNewModel indirectly inherits the properties of Swiftnew and Car.
class Car { String nameOfCompany = "Suzuki"; boolean isACAvail = true; int numberOfTyre = 4; public void getCarDetails() { System.out.println("Company name of Car = "+ nameOfCompany); System.out.println("Is AC available in car = "+ isACAvail); System.out.println("Number tyres in Car = "+ numberOfTyre); } } class SwiftNew extends Car { String carName = "Swift"; String modelName = "Vxi"; String color = "white"; public void getModelDetails() { System.out.println("Name of Car = "+ carName); System.out.println("Model name = "+ modelName); System.out.println("Color of model = "+ color); } } public class SwiftNewModel extends SwiftNew { boolean autoMatic = true; public void newSwiftFeature() { System.out.println("The new model of swift is Automatic = "+ autoMatic); } public static void main(String arg[]) { SwiftNewModel newSwiftModel = new SwiftNewModel (); newSwiftModel.getCarDetails(); newSwiftModel.getModelDetails(); newSwiftModel.newSwiftFeature(); } }
Output: Company name of Car = Suzuki
Is AC available in car = true
Number tyres in Car = 4
Name of Car = Swift
Model name = Vxi
Color of model = white
The new model of swift is Automatic = true
3. Hierarchical Inheritance
In hierarchical inheritance, more than one derived class can inherit the properties of one base class. There is only one base class and the derived class can be more than one.
Example: In this example, we have three classes. Car is the base class, and Swift and Alto are derived classes. The Swift and Alto, both are indirectly inheriting the properties of the class Car.
class Car { String nameOfCompany = "Suzuki"; boolean isACAvail = true; int numberOfTyre = 4; public void getCarDetails() { System.out.println("Company name of Car = "+ nameOfCompany); System.out.println("Is AC available in car = "+ isACAvail); System.out.println("Number tyres in Car = "+ numberOfTyre); } } class Swift extends Car { String carName = "Swift"; String modelName = "Vxi"; String color = "white"; public void getModelDetails() { System.out.println("Name of Car = "+ carName); System.out.println("Model name = "+ modelName); System.out.println("Color of model = "+ color); } } class Alto extends Car { String carName = "Alto"; String modelName = "Zxi"; String color = "Black"; public void getModelDetails() { System.out.println("Name of Car = "+ carName); System.out.println("Model name = "+ modelName); System.out.println("Color of model = "+ color); } } public class AllCars { public static void main(String arg[]) { // We can get information by creating the separate objects Swift swift = new Swift(); swift.getCarDetails(); swift.getModelDetails(); Alto alto = new Alto(); alto.getCarDetails(); alto.getModelDetails(); } }
Output: Company name of Car = Suzuki
Is AC available in car = true
Number tyres in Car = 4
Name of Car = Swift
Model name = Vxi
Color of model = white
Company name of Car = Suzuki
Is AC available in car = true
Number tyres in Car = 4
Name of Car = Alto
Model name = Zxi
Color of model = Black
Interface inheritance in java
As you know inheritance is an important concept/feature of Object-Oriented Programming. Inheritance is a mechanism by which one class can acquire/inherit the features(fields and methods) of another class. Similarly, an interface can inherit another interface also. An interface can extend any number of interfaces.
The interface CollegeInfo extends the interface PersonalInfo. That means, that the CollegeInfo inherits all fields and methods from PersonalInfo. When any class will implement CollegeInfo, that class has to provide the implementation of all methods that are declared in both CollegeInfo and PersonalInfo.
How to extend multiple interfaces in java
A class can’t extend more than one class, but an interface can extend any number of interfaces. Now we will see how to extend multiple interfaces in Java.
You specify that by listing the names of all interfaces to inherit from, separated by a comma.
A class can extend to another class and can also implement one or more interfaces. Finally, We will see how we can do this. Here we are creating a class FirstClass and two more interfaces that are FirstInterface and Secondnterface. We are creating one more class(Derived class) separately that is extending the FirstClass and also implementing both interfaces. The Derived class has to implement all methods defined in both FirstInterface and SecondInterface.
interface FirstInterface { void showFirstInterface(); } interface SecondInterface { void showSecondInterface(); } class FirstClass { void showFirstClass() { System.out.println("This is the method of FirstClass"); } } // class implements both interfaces // and provides implementation to the method. class DerivedClass extends FirstClass implements FirstInterface, SecondInterface { @Override public void showSecondInterface() { System.out.println("It is implementation of Second interface"); } @Override public void showFirstInterface() { System.out.println("It is implementation of First interface"); } } public class MainClass { public static void main (String[] args) { DerivedClass derived = new DerivedClass(); // calling the method implemented // within the class. derived.showFirstInterface(); derived.showSecondInterface(); derived.showFirstClass(); } }
Output:
It is the implementation of the First interface
It is the implementation of the Second interface
This is the method of FirstClass
An interface can extend to another interface. If an interface extends another interface, all the abstract methods of the base interface copy to the derived interface.
Multiple inheritances using the interface in java
You can also read Why Java doesn’t support multiple inheritances? We can achieve it through interfaces.
In JAVA 8, you can define default methods in an interface. By use of default methods, you can provide a default implementation of methods. Also, a class can implement any number of interfaces. If interfaces contain the same default methods with the same signature, the implementing class should explicitly specify which default method is to be overridden.
interface FirstInterface { // default method default void showData() { System.out.println("Default method of FirstInterface"); } } interface SecondInterface { // Default method default void showData() { System.out.println("Default method of SecondInterface"); } } // Implementation class code public class MainClass implements FirstInterface, SecondInterface { @Override public void showData() { FirstInterface.super.showData(); SecondInterface.super.showData(); } public static void main(String args[]) { ExampleOfSleepMethod d = new ExampleOfSleepMethod(); d.showData(); } }
Output: Default method of FirstInterface
Default method of SecondInterface
As you can see in the above example, we are implementing two interfaces (FirstInterface and SecondInterface) in the class MainClass. Hence, The MainClass overrides the show() method. To access the method from different interfaces we are using the super keyword. So, You can resolve the ambiguity of multiple interfaces by the use of a super keyword.
Type Casting in Inheritance
As you know inheritance in Java is a very important topic in object-oriented programming. Here we will discuss the typecasting of the object. These are the important inheritance rule that should be discussed.
Case 1: Parent class reference can hold the child class object but vice versa is not possible.
class Parent { String name = "Ram"; public void printData() { System.out.println("Name of person = "+ name); } } class Child extends Parent { int age = 25; public void showData() { System.out.println("Age of person = "+ age); } } class MainClass { public static void main (String [] args) { Parent parent = new Child(); parent.printData(); } }
Output: Name of person = Ram
Let’s try what will happen if the Child class reference holds the Object of a parent class.
class Parent { String name = "Ram"; public void printData() { System.out.println("Name of person = "+ name); } } class Child extends Parent { int age = 25; public void showData() { System.out.println("Age of person = "+ age); } } class MainClass { public static void main (String [] args) { Child c = (Child) new Parent(); } }
Output: Exception in thread “main” java.lang.ClassCastException: Parent cannot be cast to Child at MainClass.main(MainClass.java:23)
Case 2: The reference of the parent class can’t access the variables and functions of a child class. If you try to access the method of the child class by Parent’s class object, then the compiler will show an error.
class Parent { String name = "Ram"; public void printData() { System.out.println("Name of person = "+ name); } } class Child extends Parent { int age = 25; public void showData() { System.out.println("Age of person = "+ age); } } class MainClass { public static void main (String [] args) { Parent parent = new Child(); parent.showData(); } }
Output: Exception in thread “main” java.lang.Error: Unresolved compilation problem: The method showData() is undefined for the type Parent at MainClass.main(MainClass.java:24)
parent.showData() will show compilation error. Because showData() is defined in the Child class.
The solution to the problem: You can create the reference and object of the Child class. Because the Child class inherits all the features of the Parent class. So, the object of a child class can access the variables and methods of both classes. It is the most common and important point about inheritance in java.
class Parent { String name = "Ram"; public void printData() { System.out.println("Name of person = "+ name); } } class Child extends Parent { int age = 25; public void showData() { System.out.println("Age of person = "+ age); } } class MainClass { public static void main (String [] args) { Child child = new Child(); child.printData(); child.showData(); } }
Output:
Name of person = Ram
Age of person = 25
Inheritance and method overriding
How do inheritance and method overriding work together? What are the method overriding rules in java and how we should take care of that? We will discuss all the method overriding rules in java with examples.
Here is the table content of the article will we will cover this topic.
1. What is Method overriding with inheritance?
2. Rules of Method overriding in inheritance?
What is Method overriding with inheritance?
If the parent class and child class have a method with the same signatures, then it’s called method overriding.
Let’s say a parent class has a method sum(int, int) and a child class provides the specific implementation of the method (sum(int, int)) that has been declared in the parent class. It is known as method overriding.
class ParentClass { // Overridden method public void printData() { System.out.println("In this method we are showing the details of Parent class"); } } class ChildClass extends ParentClass { //Overriding method public void printData() { System.out.println("In this method we are showing the details of child class"); System.out.println("We are overriding the method"); } public static void main( String args[]) { ParentClass parentObject = new ChildClass(); //This will call the child class method parentObject.printData(); } }
Output:
In this method we are showing the details of child class
We are overriding the method
Advantages of method overriding:
Method overriding is only possible in inheritance. In method overriding the derived class can give its own specific implementation to an inherited method. You can provide the implementation to the method in the derived class without even modifying the parent class code.
Rules of method overriding in inheritance
1. Argument/Parameters list
The argument/parameter list of the overriding method (of the child class) must be the same as the Overridden method(the method of the parent class).
- You can’t change the number of arguments.
- You can’t change the data type of arguments or their sequence should exactly match.
If you change anything in the arguments of the method of the child class, then it doesn’t consider method overriding.
2. Access modifier
The overriding method (method of the child class) can’t be more restrictive than the overridden method (method of the parent class).
Example: If the Access Modifier of the overridden method (method of Parent class) is public then the overriding method (the child class method ) can’t be private, protected, and default access modifier because all three access modifiers are more restrictive than public. We can read Access Modifier from here
class ParentClass { // Overridden method public void printData() { System.out.println("In this method we are showing the details of Parent class"); } } class ChildClass extends ParentClass { //Overriding method private void printData() { System.out.println("In this method we are showing the details of child class"); System.out.println("We are overriding the method"); } public static void main( String args[]) { ChildClass childObject = new ChildClass(); //This will call the child class method childObject.printData(); } }
Output:
Exception in thread “main” java.lang.Error: Unresolved compilation problem: Cannot reduce the visibility of the inherited method from ParentClass at ChildClass.printData(ChildClass.java:12) at ChildClass.main(ChildClass.java:20)
3. Private methods can’t override
Private methods can’t be overridden as they are local to the class. You can’t inherit the private variables and methods of the parent class.
class ParentClass { private void printData() { System.out.println("In this method we are showing the details of Parent class"); } } class ChildClass extends ParentClass { //Overriding method private void printData() { System.out.println("In this method we are showing the details of child class"); System.out.println("We are overriding the method"); } public static void main( String args[]) { ParentClass obj = new ChildClass(); //This will call the child class method obj.printData(); } }
Output: Exception in thread “main” java.lang.Error: Unresolved compilation problem: The method printData() from the type ParentClass is not visible at ChildClass.main(ChildClass.java:19)
We are getting the compiler error because the printData() has a private access modifier in the ParentClass. The compiler tried to call the ChildClass function, but it’s not overridden.
4. static methods can’t override
If you have a static method in the ParentClass and you define a static method with same signature as a static method in the Childclass. In this case, the ChildClass method would act differently. it is known as method hiding.
class Parent { // Static method in base class static void showData() { System.out.println("This is Static method of Parent class"); } } class Child extends Parent { // static method in drived class static void showData() { System.out.println("This is Static method of child class"); } } class MainClass { public static void main(String[] args) { Parent parent = new Child(); parent.showData(); } }
Output: This is Static method of Parent class
As you know Static method can directly be called with the class name. In this example, we are calling the showData() method by reference to the Parent class then the compiler converts.
5. final methods can’t override
The final keyword in java uses to apply restrictions on some functionalities. If we declare any method with the final keyword it means we can’t change its implementation in the child class. So, Java doesn’t permit the override of any final method.
Example:
class Parent { // final method in base class final void showData() { System.out.println("This is Static method of Parent class"); } } class Child extends Parent { // final method in drived class final void showData() { System.out.println("This is Static method of child class"); } } class MainClass { public static void main(String[] args) { Parent parent = new Child(); parent.showData(); } }
Output: The above example will show compilation error
6. Overriding and constructor
You can’t overload the constructor of the parent class. Because the Constructor name must always be the same as for Class name and it doesn’t inherit.
Difference between inheritance and composition
Re-usability restriction
Inheritance: In Inheritance, you can only extend only one class. You can’t extend more than one class. It means you can reuse the code of only one class.
Composition: By the use of Composition, we can use functionalities from multiple classes. In Java, multiple inheritances don’t support so in that you must use Composition.
Static vs Dynamic
Inheritance: In Inheritance, if we want to use the functionality of any class then We have to tell the compiler. So we use extend keyword to inherit the functionality and we can’t change it at runtime.
Composition: By the use of Composition we just need to define a type that we want to use. It can hold its different implementation. The composition provides more flexibility than Inheritance.
Unit testing
Composition: If your application is designed by the use of Composition then it is easier to test because you can supply the mock implementation of the classes.
Final classes
Inheritance: Suppose your application has some final classes and you want to use the functionality of those classes. But you can’t use them through inheritance. Because as per the Java rule final class can’t be inherited.
Composition: By use of composition you can use the functionality from final classes.