简体   繁体   中英

Inheritance vs Composition: Does composition effectively solve dependency issues? [Effective Java]

I'm semi-familiar with Java and came across something in Effective Java(2017) that didn't make much sense to me.

Below is a piece from the book. (item 18)

Unlike method invocation, inheritance violates encapsulation. In other words, a subclass depends on the implementation details of its superclass for its proper function. The superclass's implementation may change from release to release, and if it does, the subclass may break, even though its code has not been touched. As a consequence, a subclass must evolve in tandem with its superclass, unless the superclass's authors have designed and documented it specifically for the purpose of being extended.

I understand composition may be favored over inheritance in some cases and understood other parts of item 18. However, I find it hard to understand how the composition method prevents the problem mentioned in the paragraph above(dependency on implementation details) - as the author speaks as though composition is better than inheritance because of this. Later in the chapter, Bloch gives an example of a custom Set implementation where he uses a Forwarding Class (which is obviously dependent on the Set interface details). One could argue the Set interface doesn't change as often but in practice changes in the interface may as well cause the Wrapper Class to break(note the book gives an example via Forwarding Class and Wrapper Class).

I guess it makes sense if Bloch meant composition is relatively safer than inheritance because class implementations change more often than interfaces. However, I think there is still a dependency issue between Wrapper Class and Interface, and am confused on why the author didn't mention this more clearly.

Am I mistaken in thinking like this?

(In addition, I'm not sure what encapsulation has to do with this. My understanding of encapsulation is hiding variables using private..)

You should actually provide more on the examples ie "Later in the chapter, Bloch gives an example of a custom Set implementation"

Basically the inheritance is that the child class will be affected by the change of parent class. See code below:

public class Baby extends Human{

}

In the code above, if Human implement another public or protected method, Baby will be forced to automatically inherit it. It is quite stringent.

But for composition, a change in the Owner object does not really require a change in the child object, and vice versa up to a certain degree.

public class Human{
  private Baby baby;
}

In the code above, Human can have any implementation that may not impact Baby and vice versa. There is more leeway for designing what Baby and Human can do. They can be entirely having lots of different properties and methods.

Ok so I looked up what @LeiYang recommended and came to realize the my question wasn't valid. The given paragraph states "a subclass depends on the implementation details of its superclass for its proper function" - which Object Composition would have no problem with, as it merely makes use of provided methods as is(without overriding). Therefore Object Composition doesn't violate encapsulation and is relatively stable compared to Inheritance .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM