2013-10-02 1 views
8

Я слышал это favor composition over inheritance снова и снова в шаблонах дизайна. некоторые из причин, указанных для этого являютсяПочему наследование сильно связано, когда композиция слабо связана с Java?

1)Inheritance is strongly coupled where as composition is loosely coupled 
2) Inheritance is compile time determined where as composition is run-time 
3)Inheritance breaks encapsulation where as composition does not 
4) anything else I am not aware of 

Было бы отлично подходит для начинающих, как мне следовать их иллюстрациями о том, как наследование и композиция отличается по отношению к вышеуказанным пунктам. Я прочитал различные ссылки SO, которые говорят о них, но прохождение примеров по этим ключевым моментам было бы замечательно для начинающих Java.

Я думаю, что очень важно понять разницу, а не просто запоминать точки.

+3

Некоторые из пронумерованных пунктов, приведенных выше, могут включать в себя фразу «может» или «может быть». –

+0

[Эта хорошая статья] (http://www.javaworld.com/jw-11-1998/jw-11-techniques.html) ответит на вопрос изящно. – Sage

ответ

1

Наследование выражается в коде с использованием расширений для конкретных классов. Когда вы его напишете, вы не сможете изменить его, не переписывая классы. Я могу изменить только путем изменения кода.

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

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

Я могу только изменить то, что делает Bar путем изменения одного или обоих классов.

Состав обычно зависит от интерфейса, а это значит, что вы указываете, что сделано, а не как. Вы можете изменить способ, не затрагивая клиентов, просто изменив реализацию интерфейса.

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(); } 
} 

я могу изменить поведение Bar в этом случае просто пропускание другой реализации интерфейса Foo.

Это один из принципов SOLID Боба Мартина: The Open/Closed Principle.

+0

даже с интерфейсом, который реализует интерфейс, должен реализовывать методы интерфейса, который включает в себя переписывание реализаций в классе реализации ..? –

+0

Имеет ли композиция * * использовать интерфейс? Не можете ли вы использовать конкретный «класс»? –

+0

Интерфейс лучше, ИМО. – duffymo

5

Хороший вопрос и большой для новичка, я думаю, что я должен сначала напомнить наследство и состав, а затем пойти, чтобы объяснить, что именно Favor Composition over Inheritance означает.

проза и минусы наследования:

Преимущества:

  • Одним из главных преимуществ динамического связывания и полиморфизма, что они могут помочь сделать код проще изменить
  • Новая реализация проста, так как большая часть ее наследуется. Простота модифицирует или расширяет повторную реализацию.

Недостатки:

  • разрываются инкапсуляция, так как он предоставляет подкласс реализации
    детали своего супер-класса
  • White-box повторного использования памяти, поскольку внутренние детали супер-классов часто видны субарендам.
  • Подклассы, возможно, придется изменить, если реализация изменений суперкласса . Реализации, унаследованные от суперклассов, могут быть изменены во время выполнения. .

О вопросе:

Наследование неидеальной, где, как композиция слабосвязанная

Наследование принесет вам тесную связь, просто одно изменение базового класса может нарушить многие ребенка классы.

Но когда использовать и как обнаружить, нам нужно наследование или состав?
Использование наследования только тогда, когда все следующие критерии удовлетворены (Правило ОЗЛ в):

  1. Подкласс выражает is a special kind of и не is a role played by a.
  2. Экземпляр подкласса никогда не должен стать объектом другого класса
  3. подкласс расширяет, а не переопределяет или аннулирует, обязанности его супер-класса
  4. подкласс не расширяет возможности что это просто утилита класса
  5. Для класса в актуальной проблемной области, подкласс специализируется роли, транзакции или устройство

Наследование - это время компиляции, когда время композиции составлено

При компиляции коды базового класса будут добавлены к каждому дочернему классу.

Наследование нарушает инкапсуляцию, где, как композиция не

Да .Увидь недостаток наследования.

Суть:

Убедитесь, что модели наследования является-связь Моя основная руководящая философия заключается в том, что наследование должно использоваться только тогда, когда подкласс-суперкласс. В приведенном выше примере, скорее всего, Apple - это плод, поэтому я бы склонен использовать наследование. Важным вопросом, который задают себе, когда вы думаете, что у вас есть отношения, является то, является ли это -отношение постоянным на протяжении всего срока службы приложения и, с удачей, жизненный цикл кода. Например, вы можете подумать, что Employee is-Person, когда действительно Employee представляет роль, которую Человек играет часть времени. Что делать, если человек становится безработным? Что, если человек является одновременно Работником и Супервизором? Такой непостоянный - отношения обычно должны быть смоделированы с составом.

Не использовать наследование только, чтобы получить повторное использование кода Если все, что вы действительно хотите, не является повторным использованием кода и нет есть, отношения в поле зрения, использование композиция.

Не использовать наследование лишь добраться до полиморфизма Если все, что вы действительно хотите полиморфизм, но не является естественным-связь, использование композиции с интерфейсами.

Фавор композиция Over Наследование :)

Я взял его прямо из javaworld.

+1

похоже, что вы скопировали и вставили с http://www.javaworld.com/jw-11-1998/jw-11-techniques.html?page=3. –

+0

его общий вопрос, и я пытаюсь объяснить шаг за шагом. Я пытаюсь вам помочь. да, часть ответа - это просто копия и прошлое. – jdev

+0

Спасибо и +1 .. –