preface

For class extension, we know there are two ways, one is: inheritance and composition. So what’s the difference between inheritance and composition? Why is composition better than inheritance

The body of the

Difference between composition and inheritance:
combination inheritance
has-a is-a
Non-destructive encapsulation Breaking encapsulation, subclasses depend on their parent class
Support extension, add composite classes at will Only one parent class can be inherited and must contain all methods, increasing system complexity
  • Inheritance is an IS-A relationship, just like a bird is an animal. And composition is has-A, just like birds have animal characteristics.
  • Inheritance breaks encapsulation because subclasses depend on their parent, whereas composition does not
  • An inherited subclass can inherit only one parent class and must contain all methods, while a composite class supports extension and can be added at will.
How does inheritance break encapsulation

A popular example is given by Lord Jingfan: I want to take jiamei’s cup, but this cup belongs to Jiamei, so I want to move jiamei out, but Jiamei belongs to the forest, so I want to move the forest out… But we all forget that my original goal was to “get the beautiful cup.”

How do YOU replace inheritance with composition

Look at the following example:

public class A {
    // The method function is to speak
    public void say() {
        // A bunch of implementation details for speaking
    }
    // The method function is singing
    public void song() {
        // Specific implementation details
        // Sing before you speak, so call your own say() method
        say();
        // Then a bunch of singing implementation details}}Copy the code
public class B extends A{
    @Override
    public void say() {
        // I just wanted to let everyone know before I speak again that I'm going to speak
        System.out.println("I'm going to start talking.");
        super.say();
    }

    @Override
    public void song() {
        // I just wanted to let everyone know that I'm going to sing before I sing again
        System.out.println("I'm going to start singing.");
        super.song();
    }

    public static void main(String[] args) {
        B b = new B();
        // Now I want to sing a songb.song(); }}Copy the code

The results of

I'm gonna start singing and I'm gonna start talkingCopy the code

This result how is like this, I just want to sing, why also said that I began to speak, because actually inherited class A and class B in the class A song using the implementation details say () method, which lead to go first in the class B song () method, left again say () method, but for class B I don’t want to know you go what way, I just want the function, singing is singing, talking is talking. We can also change the song() method of class A to not call say(), but this should not be related to the implementation details of class A. I only provide my API interface, and I should be able to change the internal implementation details of class A. So that’s the problem with inheritance leaking the implementation details of the API. Composition has no such problem, putting class A into class B as A private field. Call the song() method of class A

public class B {
    private A a;

    public B(A a) {
        this.a = a;
    }
    public void say() {
        System.out.println("I'm going to start talking.");
        a.say();
    }

    public void song() {
        System.out.println("I'm going to start singing.");
        a.song();
    }
    
    public static void main(String[] args) {
        B b = new B(new A());
        // Now I want to sing a songb.song(); }}Copy the code

The results of

I'm going to start singingCopy the code

As you can see, composition hides the implementation details of a class and focuses on functionality rather than detail

Therefore, inheritance should strictly follow the IS-A relationship, otherwise, inheritance should not be used blindly. When using inheritance, we should consider whether inheritance is just for extending functions. Otherwise you have to use composition instead of inheritance.

Examples from: blog.csdn.net/weixin_4413…