why inheritance is strongly coupled where as composition is loosely coupled in Java? [duplicate]

巧了我就是萌 提交于 2019-11-30 03:54:10
jdev

Nice question and big for a beginner, I think I should first remind the reader what inheritance and composition are, and then go on to explain what exactly Favor Composition over Inheritance means.

Pros and Cons of Inheritance :

Advantages:

  • One of the prime benefits of dynamic binding and polymorphism is that they can help make code easier to change.
  • New implementation is easy, since most of it is inherited. It's easy to modify or extend the implementation being reused.

Disadvantages:

  • Breaks encapsulation, since it exposes a subclass to implementation
    details of its super-class.
  • White-box reuse, since internal details of super-classes are often visible to subclasses.
  • Subclasses may have to be changed if the implementation of the superclass changes. Implementations inherited from superclasses can not be changed at runtime.

About the question:

Inheritance is strongly coupled where as composition is loosely coupled

Inheritance will bring you tight coupling, simply one change to base class can break many child classes.

But when to use and how detect we need inheritance or composition?
Use inheritance only when all of the following criteria are satisfied (Coad's Rule):

  1. A subclass expresses is a special kind of and not is a role played by a.
  2. An instance of a subclass never needs to become an object of another class.
  3. A subclass extends, rather than overrides or nullifies, the responsibilities of its super-class.
  4. A subclass does not extend the capabilities of what is merely a utility class.
  5. For a class in the actual Problem Domain, the subclass specializes a role, transaction or device.

Inheritance is compile time determined where as composition is run-time

When compiled, your base class codes will be added to every child class.

Inheritance breaks encapsulation where as composition does not

Yes. Now you see the disadvantage of inheritance.

The bottom line is:

Make sure inheritance models the is-a relationship My main guiding philosophy is that inheritance should be used only when a subclass is-a superclass. In the example above, an Apple likely is-a Fruit, so I would be inclined to use inheritance.

An important question to ask yourself when you think you have an is-a relationship is whether that is-a relationship will be constant throughout the lifetime of the application and, with luck, the lifecycle of the code. For example, you might think that an Employee is-a Person, when really Employee represents a role that a Person plays part of the time. What if the person becomes unemployed? What if the person is both an Employee and a Supervisor? Such impermanent is-a relationships should usually be modelled with composition.

Don't use inheritance just to get code reuse If all you really want is to reuse code and there is no is-a relationship in sight, use composition.

Don't use inheritance just to get at polymorphism If all you really want is polymorphism, but there is no natural is-a relationship, use composition with interfaces.

Favor composition Over Inheritance :)

I took it straight from the javaworld.

Inheritance is expressed in code using extends for concrete classes. Once you write it, you can't change it without rewriting the classes. I can only change by modifying code.

public class Foo {
    public void doSomething() { System.out.println("I'm a Foo"); }
}

public class Bar extends Foo {
    public void doSomething() { super.doSomething(); }
}

I can only change what Bar does by modifying one or both classes.

Composition is usually interface-based, which means that you specify what is done, not how. You can change the how without affecting clients simply by changing the implementation of the interface.

public interface Foo {
    void doSomething();
}

public class FooImpl implements Foo {
    public void doSomething() { System.out.println("I'm a Foo"); }
}

public class Bar implements Foo {
    private Foo foo;

    public Bar(Foo f) { this.foo = f; }

    public void doSomething() { this.foo.doSomething(); }
}

I can change the behavior of Bar in this case simply by passing a different implementation of the Foo interface.

It's one of Bob Martin's SOLID principles: The Open/Closed Principle.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!