Difference between Inheritance and Composition

246,898

Solution 1

They are absolutely different. Inheritance is an "is-a" relationship. Composition is a "has-a".

You do composition by having an instance of another class C as a field of your class, instead of extending C. A good example where composition would've been a lot better than inheritance is java.util.Stack, which currently extends java.util.Vector. This is now considered a blunder. A stack "is-NOT-a" vector; you should not be allowed to insert and remove elements arbitrarily. It should've been composition instead.

Unfortunately it's too late to rectify this design mistake, since changing the inheritance hierarchy now would break compatibility with existing code. Had Stack used composition instead of inheritance, it can always be modified to use another data structure without violating the API.

I highly recommend Josh Bloch's book Effective Java 2nd Edition

  • Item 16: Favor composition over inheritance
  • Item 17: Design and document for inheritance or else prohibit it

Good object-oriented design is not about liberally extending existing classes. Your first instinct should be to compose instead.


See also:

Solution 2

Composition means HAS A
Inheritance means IS A

Example: Car has a Engine and Car is a Automobile

In programming this is represented as:

class Engine {} // The Engine class.

class Automobile {} // Automobile class which is parent to Car class.

class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}

Solution 3

How inheritance can be dangerous ?

Lets take an example

public class X{    
   public void do(){    
   }    
}    
Public Class Y extends X{
   public void work(){    
       do();    
   }
}

1) As clear in above code , Class Y has very strong coupling with class X. If anything changes in superclass X , Y may break dramatically. Suppose In future class X implements a method work with below signature

public int work(){
}

Change is done in class X but it will make class Y uncompilable. SO this kind of dependency can go up to any level and it can be very dangerous. Every time superclass might not have full visibility to code inside all its subclasses and subclass may be keep noticing what is happening in superclass all the time. So we need to avoid this strong and unnecessary coupling.

How does composition solves this issue?

Lets see by revising the same example

public class X{
    public void do(){
    }
}

Public Class Y{
    X x = new X();    
    public void work(){    
        x.do();
    }
}

Here we are creating reference of X class in Y class and invoking method of X class by creating an instance of X class. Now all that strong coupling is gone. Superclass and subclass are highly independent of each other now. Classes can freely make changes which were dangerous in inheritance situation.

2) Second very good advantage of composition in that It provides method calling flexibility, for example :

class X implements R
{}
class Y implements R
{}

public class Test{    
    R r;    
}

In Test class using r reference I can invoke methods of X class as well as Y class. This flexibility was never there in inheritance

3) Another great advantage : Unit testing

public class X {
    public void do(){
    }
}

Public Class Y {
    X x = new X();    
    public void work(){    
        x.do();    
    }    
}

In above example, if state of x instance is not known, it can easily be mocked up by using some test data and all methods can be easily tested. This was not possible at all in inheritance as you were heavily dependent on superclass to get the state of instance and execute any method.

4) Another good reason why we should avoid inheritance is that Java does not support multiple inheritance.

Lets take an example to understand this :

Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b = new Deposit();    
        if(b.deposit()){    
            b = new Credit();
            c.credit();    
        }
    }
}

Good to know :

  1. composition is easily achieved at runtime while inheritance provides its features at compile time

  2. composition is also know as HAS-A relation and inheritance is also known as IS-A relation

So make it a habit of always preferring composition over inheritance for various above reasons.

Solution 4

The answer given by @Michael Rodrigues is not correct (I apologize; I'm not able to comment directly), and could lead to some confusion.

Interface implementation is a form of inheritance... when you implement an interface, you're not only inheriting all the constants, you are committing your object to be of the type specified by the interface; it's still an "is-a" relationship. If a car implements Fillable, the car "is-a" Fillable, and can be used in your code wherever you would use a Fillable.

Composition is fundamentally different from inheritance. When you use composition, you are (as the other answers note) making a "has-a" relationship between two objects, as opposed to the "is-a" relationship that you make when you use inheritance.

So, from the car examples in the other questions, if I wanted to say that a car "has-a" gas tank, I would use composition, as follows:

public class Car {

private GasTank myCarsGasTank;

}

Hopefully that clears up any misunderstanding.

Solution 5

Inheritance brings out IS-A relation. Composition brings out HAS-A relation. Strategy pattern explain that Composition should be used in cases where there are families of algorithms defining a particular behaviour.
Classic example being of a duck class which implements a flying behaviour.

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

 public Duck(){
  fly = new BackwardFlying();
 }
}

Thus we can have multiple classes which implement flying eg:

public class BackwardFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies backward ");
  }
}
public class FastFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies 100 miles/sec");
  }
}

Had it been for inheritance, we would have two different classes of birds which implement the fly function over and over again. So inheritance and composition are completely different.

Share:
246,898

Related videos on Youtube

gmhk
Author by

gmhk

Bangalore, India, Dream to Develop a Web Eco System where all Internet users can interact and exchange Ideas. Always work on New innovative Ideas with latest technology

Updated on May 23, 2020

Comments

  • gmhk
    gmhk about 4 years

    Are Composition and Inheritance the same? If I want to implement the composition pattern, how can I do that in Java?

  • nanofarad
    nanofarad over 10 years
    I'd change "automobile" to "powered vehicle" as in many interpratations cars and automobiles are equivalent.
  • Scott Solmer
    Scott Solmer over 10 years
    Link only answers are discouraged because they go stale. Please include at least the most important relevant information from the link in your answer.
  • nckbrz
    nckbrz about 10 years
    @hexafraction I agree that Vehicle would likely be a better choice, but at the same time -codaddict- has illustrated the point just fine for what has been asked.
  • qed
    qed over 9 years
    Interesting. Why not just create a new class java.util.Stack2 that uses composition?
  • Thomas
    Thomas over 9 years
    I appreciate this answer; however, I feel as if the answer gets off track and delves more into concerns surrounding the design of the language (and a particular package) than it does answer the asked question regarding composition vs. inheritance. I am a big fan of answering the question on SO, citing resources - not linking to external resources without providing a more in depth summary than a one-line summation.
  • ThePyroEagle
    ThePyroEagle over 8 years
    Java conventions state that class and interface names are written in ThisCase, not in camelCase. Therefore it is best to name your interfaces IDrivable, etc. You might not need the "I" if you regroup all your interfaces into a package correctly.
  • Omar Tariq
    Omar Tariq over 7 years
    "an Engine" :-/
  • Sam Ramezanli
    Sam Ramezanli over 7 years
    Bad example, I had to do extra search to understand what Vector and Stack are.
  • roottraveller
    roottraveller almost 7 years
    nicely expained. +1. further reading javarevisited.blogspot.in/2015/06/…
  • QMaster
    QMaster over 6 years
    Good but your example about java stack is not a good candidate because of this inheritance is a sample of bad decision about choosing inheritance over composition as said in this article: thoughtworks.com/insights/blog/…
  • Mathews Sunny
    Mathews Sunny over 6 years
    Its only comment quality
  • Anjil Dhamala
    Anjil Dhamala over 6 years
    Did you just comment the same thing the accepted answer said 7 years before you?
  • bhalkian
    bhalkian over 6 years
    Does it make sense to implement parts for car class as well . Will it not be good if you use it as composition
  • Ojonugwa Jude Ochalifu
    Ojonugwa Jude Ochalifu almost 6 years
    @AndreyAkhmetov Automobile can have type field of Type Enum
  • nanofarad
    nanofarad almost 6 years
    @ojonugwaochalifu I don't understand how that ties into my statement (which was five years ago so perhaps I have forgotten the context here). I was referring to the descriptiveness of type names rather than any addition of enums (which don't apply to this answer)
  • stuckedoverflow
    stuckedoverflow over 5 years
    agree but given your solution using composition....we still need do a babysit for example now super class X change the method name from do to doing....then sub class Y will also need to be maintained (needs to be changed as well) this is still tight coupling? And how do we get rid of it?
  • Kröw
    Kröw about 5 years
    Why should I "perfer Composition over Inheritance"? They are different concepts and are used for different purposes. Frankly, I don't see how you could even go from one to the other.
  • Hrishabh Gupta
    Hrishabh Gupta about 3 years
    What are the cons of Duck implementing BackwardFlying or BackwardFlyer?
  • Hrishabh Gupta
    Hrishabh Gupta about 3 years
    @stuckedoverflow Changing contract either by name or signature is anti-pattern. New extensions are, however, are acceptable. (O in SOLID)