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.

Tuesday, February 7, 2017

Introduction to Java's Inheritance and Interfaces - Part 2

Contd...

Lets now use the above classes in main program:
Objective: Based on an input from a user, the program has to use code from either Car or BenzCar or BMWCar.
Requirment: If the entry from use is Car then use the code from Car class similary for Benz and BMW.

Solution:
public class InheritanceDemo{
public static void main(String[] args){
if(args[0].equals("Car")){
Car car = new Car();
car.drive();          //Prints This is default drive implementation
car.accelerate();     //Prints This is default accelerate implementation
car.applyBrakes();    //Prints This is default applyBrakes implementation
}
else if(args[0].equals("Benz"){
BenzCar benz = new BenzCar();
benz.drive();         //Prints This is default drive implementation
benz.accelerate();    //Prints Accelerate slowly and steadily.
benz.applyBrakes();  //Prints This is default applyBrakes implementation
}
else if(args[0).equals("BMW"){
BMWCar bmw = new BMWCar();
bmw.drive();          //Prints Drive or move at highest speed all the time
bmw.accelerate();     //Prints Accelerate at brisk speed but steadily.
bwm.applyBrakes();    //Prints This is default applyBrakes implementation
}
else
System.out.println("Invalid Entry");
}

}

Notation: Super-class referencing Sub class object: So far, the code looks simple but there is an issue with the code. It contains lot of repetition.

car.drive();
benz.drive();
bmw.drive();

Like-wise the other methods - accelerate() and applyBrakes().
This repetition has made the program lengthy with more number of lines of code than required. As a result the code's compilation time increases. But there is a facility provided by Java's inheritance to optimize this kind of situations.

Use of the notation: Super class referencing Sub class object

Yes. The Super-class's or Parent-class's object reference can refer to its sub-class's or child class's object.

Car car = new BenzCar();
Car car = new BMWCar();



Lets use this notation in the above program.

public class InheritanceDemo{

public static void main(String[] args){

Car car;                 //Creating a Super class's object reference.

if(args[0].equals("Car")){
car = new Car();     //Assign a Class's object to its reference.
}
else if(args[0].equals("Benz"){

car = new BenzCar(); //Assign Subclass's object to its SuperClass's reference.


}
else if(args[0).equals("BMW"){
car = new BMWCar();  //Assign Subclass's object to its SuperClass's reference.
}

else
System.out.println("Invalid Entry");

car.drive();          //Prints based on input
car.accelerate();     //Prints based on input
car.applyBrakes();    //Prints based on input


}

}

Now see, how the code has shaped up with fewer number of lines with the new notation.
A Super-Class's object can behave(or morph or act) like its sub-class's object based on the object that it refers. This is called Runtime polymorphism or Dynamic polymorphism. An important concept closely associated with efficient coding.


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...