Tuesday 8 November 2016

Composition v/s Inheritance : Which should be preferable?



Composition V/S Inheritance





Inheritance is an "is-a" relationship where as Composition is a "has-a".
Composition allows reuse of code without extending it but in case of Inheritance we must extend the class for any reuse of code or functionality.


  • With Inheritance we are defining which class we are going to extend means static binding and this can’t be changed at runtime but with Composition we just define an object type which we want to use, which can hold its different implementation during execution means dynamic binding. So we can say that using Composition is more flexible than Inheritance.

  • In case of Inheritance we can extend only one class but if we want to take advantage of multiple class functionality then we can use Composition

  • At some point of time, Inheritance breaks encapsulation because in case of Inheritance, sub class is dependent upon super class behavior and if parent classes are changed than child class will also get affected and as a result it breaks sub class functionality.


  • Composition also allows code reuse for final class and this is not possible in Inheritance because we can’t extend final class.

  •  When we are using Composition in our application then during unit testing it is easy to test because we are able to provide mock implementation of required classes but when we are using Inheritance then we required parent classes in order to test child classes and we can’t mock parent classes. 
Example of Composition and Inheritance-

Car.java

package com.inheritancecomposition.relationship;

public class Car {
    

/** Class/Instance members and Methods implementation */
    private int maxSpeed;
    private String color;

    public void setColor(String color) {
        this.color = color;
    }
    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    public void carDescription(){
        System.out.println("The "+color + " color car is running at max Speed of " + maxSpeed);
    }
}


Engine.java

package com.inheritancecomposition.relationship;

public class Engine {
    public void start(){
        System.out.println("** Engine Started **");
    }
    public void stop(){
        System.out.println("** Engine Stopped **");
    }
}


Hyundai.java

package com.inheritancecomposition.relationship;

public class Hyundai extends Car{ 
/** Inheritance is used here */
    /**
     * Hyundai extends Car and thus inherits all methods from Car (except final
     * and static) Hyundai can also define all its specific functionality
     */

    public void hyundaiStartDemo(){
        Engine hyundaiEngine = new Engine(); /** Composition is used here */
        hyundaiEngine.start();
        }
}



RelationsDemo.java

package com.inheritancecomposition.relationship;

public class RelationsDemo {
    public static void main(String[] args) {
        Hyundai myHyundai = new Hyundai();
        myHyundai.hyundaiStartDemo();
        myHyundai.setColor("Carbon Grey");
        myHyundai.setMaxSpeed(200);
        myHyundai.carDescription();
    }
}


Result:-

** Engine Started **
The Carbon Grey color car is running at max Speed of 200