Wednesday, February 8, 2017

Introduction to Java's Inheritance and Interfaces - Part 3

So far dynamic polymorphism is permitted within a Class hierarchy(thanks to Inheritance) but not across multiple hierarchies. What it means is...

Consider the following hierarchies of classes:
Parent: Car, Child1: BMWCar extends Car, Child2: BenzCar extends Car
Parent: Aeroplane, Child1: Boeing extends Aeroplane, Child2: AirBus extends Aeroplane




Now I want to create a program which uses the above class hierarchies where the requirement is to dynamically call cruise() based on a user input.
Requirement: If user enters 
     Benz   --> cruise() from BenzCar class should be executed
  BMW    --> cruise() from BMWCar class should be executed
  Boeing --> cruise() from Boeing class should be executed
  AirBus --> cruise() from AirBus class should be executed
  
Solution: 
This situation is quite common in OOPs programming. Here is the code below:

public class DemoInterface{

public static void main(String[] args){
Car car;
Airplane plane;
if(args[0].equals("Benz")){
car = new BenzCar();
}else if(args[0].equals("BMW")){
car = new BMWCar();
}else if(args[0].equals("Boeing")){
plane = new Boeing();
}else if(args[0].equals("AirBus")){
plane = new AirBus();
}else{
System.out.println("Invalid entry. Pls try again.");
}


//Calling the method
if(car != null)
car.cruise();
if(plane !=null)
plane.cruise();

}

}

Solution is okay...but observe the repetition:
car.cruise(); 
plane.cruise();

The method is called twice. Though it is necessary but can be avoided and has to be. Since this program contains just 2 different class hierarchies and we created two super-class obj-refs able to refer all other sub-class objects. But, What if it has many more.It might lead to more number of references. To optimize this situation, Java has provided Interface.

Interface(Def from Oracle):In the Java programming language, an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods. Interfaces cannot be instantiated—they can only be implemented by classes or extended by other interfaces.

I would say... Interfaces similar to SuperClass obj-ref referencing SubClass'Object for the benefits of code-optimization can do the same but accross multiple Class-Hierarchies. Its a level beyond the polymorphism achieved with Inheritance.

Notation: As in Class level inheritance, where super-class variable can refer any of its child class objects, An interface's variable too can refer any of its implementing classes. Lets use Interface in the above situation.

Figure followed by updated solution below shows how the hierarchy looks like if interface is used.



We can see, the super classes - Car & Airplane - implement CarOPlane interface containing the methods - cruise() and selfDrive(). Then, the child classes override those methods again.

Note: What methods that are qualified to be in Interface?
All those identical methods(methods with same signatures) which belong to multiple class-hierarchies can be part of Interface's definition.


Interface: 
public interface CarOPlane{
public void selfDrive();
public void cruise();
}

Updated solution:

public class DemoInterface{

public static void main(String[] args){
CarOPlane cop;                        //Creating an interface obj-ref
if(args[0].equals("Benz")){          
cop = new BenzCar();  //Assigning implementing class's object
}else if(args[0].equals("BMW")){
cop = new BMWCar();               //Assigning implementing class's object
}else if(args[0].equals("Boeing")){
cop = new Boeing();      //Assigning implementing class's object
}else if(args[0].equals("AirBus")){
cop = new AirBus();               //Assigning implementing class's object
}else{
System.out.println("Invalid entry. Pls try again.");
}


//Calling the method
if(cop != null)
cop.cruise();     //Calling the cruise() method. This is where the code is optimized

}

}


Summary of Interface benefits:
1) Code optimization: Repetition is reduced as a result code maintenance reduced too. Means..if some part of the repeated code need to be changed, it has to change at every repeated line of code.
2) Interface reference can refer objects span across multiple class hierarchies(A limitation in inheritance based). A level beyond polymorphism achieved with Inheritance.


Deadly Diamond of Death: Many Java professionals have an opinion that multiple-inheritance creates the problem of Deadly Diamond of Death(DDD) and Interface is the solution. But I wont agree. Here is my take...

In case of child-class inheriting a parent-class, the child basically inherits the code and does not require it to write the new code unless it really needs its own implementation. Hence, if a child tries to inherit from multiple parents containing identical methods(bodies may differ but do exit), the problem arises as to which parent's method need to inherit(DDD). Java does not allow this. 

But, same is not the case with Interfaces. They don't have implementation. Therefore, if a class implements several interfaces that have identical method-signatures only(but no bodies), it only imports method signatures and implements them. No confusion as to which code to implement since there is no code exist in interface's methods.

No comments:

How J2EE components work together in any Container - Spring or Application Server

In a Spring+Jersey+Hibernate RESTful webapplication, we can spot various J2EE components - JTA, JPA, Java Bean Validation, JSON-B API for B...