Tutorial

Composition vs Inheritance

Published on August 4, 2022
author

Pankaj

Composition vs Inheritance

Composition vs Inheritance is one of the frequently asked interview questions. You must have also heard to use Composition over Inheritance.

Composition vs Inheritance

Both composition and inheritance are object-oriented programming concepts. They are not tied up with any specific programming language such as Java. Before we compare composition over inheritance programmatically, let’s have a quick definition of them.

Composition

Composition is the design technique in object-oriented programming to implement has-a relationship between objects. Composition in java is achieved by using instance variables of other objects. For example, a person who has a Job is implemented like below in java object-oriented programming.

package com.journaldev.composition;

public class Job {
// variables, methods etc.
}
package com.journaldev.composition;

public class Person {

    //composition has-a relationship
    private Job job;

    //variables, methods, constructors etc. object-oriented

Inheritance

Inheritance is the design technique in object-oriented programming to implement is-a relationship between objects. Inheritance in Java is implemented using the extends keyword. For example, Cat is an Animal relationship in java programming will be implemented like below.

package com.journaldev.inheritance;
 
public class Animal {
// variables, methods etc.
}
package com.journaldev.inheritance;
 
public class Cat extends Animal{
}

Composition over Inheritance

Both composition and inheritance promote code reuse through different approaches. So which one to choose? How to compare composition vs inheritance. You must have heard that in programming you should favor composition over inheritance. Let’s see some of the reasons that will help you in choosing composition vs inheritance.

  1. Inheritance is tightly coupled whereas composition is loosely coupled. Let’s assume we have below classes with inheritance.

    package com.journaldev.java.examples;
    
    public class ClassA {
    
    	public void foo(){	
    	}
    }
    
    class ClassB extends ClassA{
    	public void bar(){
    		
    	}
    }
    

    For simplicity, we have both the superclass and subclass in a single package. But mostly they will be in the separate codebase. There could be many classes extending the superclass ClassA. A very common example of this situation is extending the Exception class. Now let’s say ClassA implementation is changed like below, a new method bar() is added.

    package com.journaldev.java.examples;
    
    public class ClassA {
    
    	public void foo(){	
    	}
    	
    	public int bar(){
    		return 0;
    	}
    }
    

    As soon as you start using new ClassA implementation, you will get compile time error in ClassB as The return type is incompatible with ClassA.bar(). The solution would be to change either the superclass or the subclass bar() method to make them compatible. If you would have used Composition over inheritance, you will never face this problem. A simple example of ClassB implementation using Composition can be as below.

    class ClassB{
    	ClassA classA = new ClassA();
    	
    	public void bar(){
    		classA.foo();
    		classA.bar();
    	}
    }
    
  2. There is no access control in inheritance whereas access can be restricted in composition. We expose all the superclass methods to the other classes having access to subclass. So if a new method is introduced or there are security holes in the superclass, subclass becomes vulnerable. Since in composition we choose which methods to use, it’s more secure than inheritance. For example, we can provide ClassA foo() method exposure to other classes using below code in ClassB.

    class ClassB {
    	
    	ClassA classA = new ClassA();
    	
    	public void foo(){
    		classA.foo();
    	}
    	
    	public void bar(){	
    	}
    	
    }
    

    This is one of the major advantage of composition over inheritance.

  3. Composition provides flexibility in invocation of methods that is useful with multiple subclass scenario. For example, let’s say we have below inheritance scenario.

    abstract class Abs {
    	abstract void foo();
    }
    
    public class ClassA extends Abs{
    
    	public void foo(){	
    	}
    	
    }
    
    class ClassB extends Abs{
    		
    	public void foo(){
    	}
    	
    }
    
    class Test {
    	
    	ClassA a = new ClassA();
    	ClassB b = new ClassB();
    
    	public void test(){
    		a.foo();
    		b.foo();
    	}
    }
    

    So what if there are more subclasses, will composition make our code ugly by having one instance for each subclass? No, we can rewrite the Test class like below.

    class Test {
    	Abs obj = null;
    	
    	Test1(Abs o){
    		this.obj = o;
    	}
    	
    	public void foo(){
    		this.obj.foo();
    	}
    
    }
    

    This will give you the flexibility to use any subclass based on the object used in the constructor.

  4. One more benefit of composition over inheritance is testing scope. Unit testing is easy in composition because we know what all methods we are using from another class. We can mock it up for testing whereas in inheritance we depend heavily on superclass and don’t know what all methods of superclass will be used. So we will have to test all the methods of the superclass. This is extra work and we need to do it unnecessarily because of inheritance.

That’s all for composition vs inheritance. You have got enough reasons to choose composition over inheritance. Use inheritance only when you are sure that superclass will not be changed, otherwise go for composition.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
May 28, 2021

I think we should not be comparing these two which one is better or not. Both inheritance and composition have different use case. Whatever is explained in the article is syntactical things. We should prefer inheritance when we want to override behavior and re usability both but composition is straight forward example of re usability, or making of small components which together can make a big component.

- Ankit Dixit

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    April 30, 2020

    Please fix the formatting issue. Everything after the Composition section is shown in code layout.

    - John

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      April 19, 2020

      Great job explaining it. There are only some formatting issues, the inheritance part is shown as it is a piece of code.

      - Malone

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        February 8, 2019

        Hi , “Now let’s say ClassA implementation is changed like below, a new method foo() is added” this statement is wrong I believe, here bar is added and not foo Thanks

        - Dinesh

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          August 27, 2017

          did not get this statement Test1(Abs o){ this.obj = o; }

          - ram kumar asak

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            August 5, 2017

            I am yet to encounter any real example to really prove this. Inheritance is “is-a” relationship. Composition is “has-a” relationship You can interchange them only if you aren’t clear about the class hierarchy. If you quote abstract examples like class A and class B you can write this but otherwise its very difficult to get it wrong. A Human is a Mammal. Can we say Human has a Mammal? Similarly a Car has an Engine, we can never say Car is an Engine. You can confuse this only if you don’t know how the relationship between your classes are? In that case I wouldn’t blindly follow “Prefer Composition vs Inheritance”. I would rather try to find out the correct relationship. Can you please discuss a real example to explain this better?

            - Shreyas Majithia

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              June 23, 2017

              Hi Pankaj, In Inheritance,cant we restrict access to the methods in super class using access modifier private and final keyword or static based on our requirement.So that those methods wont be exposed to outside world. Please clarify. Thanks, Sarathkumar

              - Sarathkumar

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                November 13, 2016

                “Now let’s say ClassA implementation is changed like below, a new method foo() is added.” should be bar not foo.

                - Yami

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  July 20, 2016

                  Nice explanation. Very clear!!!

                  - Carlos Zegarra

                    Try DigitalOcean for free

                    Click below to sign up and get $200 of credit to try our products over 60 days!

                    Sign up

                    Join the Tech Talk
                    Success! Thank you! Please check your email for further details.

                    Please complete your information!

                    Become a contributor for community

                    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                    DigitalOcean Documentation

                    Full documentation for every DigitalOcean product.

                    Resources for startups and SMBs

                    The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                    Get our newsletter

                    Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                    New accounts only. By submitting your email you agree to our Privacy Policy

                    The developer cloud

                    Scale up as you grow — whether you're running one virtual machine or ten thousand.

                    Get started for free

                    Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                    *This promotional offer applies to new accounts only.