1

Я прочитал несколько сообщений о «композиции над наследованием», «где использовать композицию/наследование», «Я-связь ...» или «Принцип замещения Лискова» в течение некоторого времени, но я не уверен, получаю ли я правильная идея о «композиции над наследованием».Является ли «состав над наследованием» просто означать «Если родительский класс никогда не используется, кроме как в классе child, он должен быть композицией»?

Кроме того, по моему опыту, «состав над наследования» кажется просто означать «Если родительский класс никогда не используется за исключением дочернего класса, он должен быть состав», например:

public class Parent{ 
} 

public class Child1 extends Parent{ 
} 

public class Child2 extends Parent{ 
} 

Если класс " Родитель "никогда не появляется в моем коде, отличном от Child1 и Child2, тогда Child1 и Child2 не должны быть дочерним классом Parent.

Это правильно?

ответ

0

Inheritance - это конкретный инструмент. Состав - общий инструмент. Оба они полезны, но в разных контекстах.

Наследование полезно, если вы хотите, чтобы все объекты типа Foo также были во всех отношениях объектами типа Bar. Это означает не просто реализацию тех же методов. Это означает, что объекты Foo должны отлично эмулировать объекты Bar в каждом видимом внешнем виде. Если они этого не сделают, то Принцип замещения Лискова будет нарушен, и наследование является плохим выбором для ситуации.

Состав гораздо более общий. Он используется для разделения обязанностей между несколькими классами, в то же время позволяя правильно абстрагировать и определять взаимодействия между ними. Это не требует конкретных, подобных Лисковам отношений, которые я только что описал.

«Композиция над наследованием» - это просто наблюдение, что композиция является более общей техникой, чем наследование. Из-за этого состав должен быть инструментом, который мы используем для первого в большинстве ситуаций, а не для наследования. Это не означает, что каждое использование наследования неверно, или даже это наследование по своей сути является плохим. Это способ мышления, а не стандарт кодирования.

0

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

0

Состав поверх наследования означает, что вместо того, чтобы структурировать иерархию классов с помощью родительского класса и extend ИНГ дочерних классов, вы должны сделать что-то вроде этого:

class Foo { 

    protected bar; 
    protected baz; 

    public function Foo(Bar _bar, Baz _baz) { 
     bar = _bar; 
     baz = _baz; 
    } 

} 

Другими словами, вместо того, чтобы наследуя куча функциональности из базового родительского класса, вы получаете эту же функциональность от независимых объектов, вместо которых вы предпочитаете впрыскивание в ваш класс.

Почему? Потому что он обеспечивает большую гибкость. В случае Foo extends Bar, Bar содержит некоторые базовые функции, которые полезны для группы наследующих классов. Теперь, кто говорит, что эта функциональность также не полезна для множества других, не связанных между собой классов? Должно ли все ваших классов наследовать от Bar? Должно ли все общая функциональность быть заполнена в Bar, потому что все классы наследуют от нее? Пожалуйста, нет, это просто приводит к жирным, монолитным, неподъемным базовым классам.

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

Вы должны наследовать только класс, если они имеют одну и ту же иерархию «бизнес-логики». Например, Cat extends Pet extends Animal имеет совершенно логичный смысл. Cat extends BaseConnectionManager нет так.

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