Я слышу (и читаю на этом сайте) много о «предпочтении композиции перед наследованием».
Но что такое композитон? Я понимаю наследование с точки зрения Person: Mammal: Animal, но нигде не вижу определения Compostion .. Может ли кто-нибудь меня заполнить?
Композиция относится к объединению простых типов в более сложные. В вашем примере композиция может быть:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal::Animal:
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person::Mammal:
string firstName
string lastName
Если вы хотите полностью перейти к композиции (и избавиться от наследования), это будет выглядеть так:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal:
private Animal _animalRef
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person:
private Mammal _mammalRef
string firstName
string lastName
Преимущество этого подхода в том, что типы Mammal
и Лицо
не обязательно должно соответствовать интерфейсу своего предыдущего родителя. Этот мог бы быть хорошей вещью, потому что иногда изменение суперкласса может иметь серьезные последствия для подклассов.
Они по-прежнему могут иметь доступ к свойствам и поведению этих классов через свои частные экземпляры этих классов, и если они хотят раскрыть эти поведения бывшего суперкласса, они могут просто заключить их в публичный метод.
Я нашел здесь хорошую ссылку с хорошими примерами: http://www.artima.com/designtechniques/compoinh.html
Композиция - это просто части, составляющие целое. У машины есть колеса, двигатель и сиденья. Наследование - это отношения «есть». Композиция - это отношение "имеет".
Есть три способа придать поведение классу. Вы можете записать это поведение в класс; вы можете наследоваться от класса, который имеет желаемое поведение; или вы можете включить класс с желаемым поведением в свой класс в качестве поля или переменной-члена. Последние два способа представляют собой формы повторного использования кода, и последний - композиция - обычно предпочтительнее. Она не дает вашему классу желаемого поведения - вам все еще нужно вызывать метод поля - но она накладывает меньше ограничений на дизайн вашего класса и приводит к тому, что код легче тестировать и легче отлаживать. Наследование имеет свое место, но композиция должна быть предпочтительнее.
class Engine
{
}
class Automobile
{
}
class Car extends Automobile // car "is a" automobile //inheritance here
{
Engine engine; // car "has a" engine //composition here
}
Состав - Функциональность объекта состоит из совокупности различных классов. На практике это означает удержание указателя на другой класс, работа которого отложена.
Наследование - Функциональность объекта складывается из его собственной функциональности плюс функциональности его родительских классов.
Что касается того, почему композиция предпочтительнее наследования, взгляните на задачу «Круг-эллипс» .
Примером Composition является случай, когда у вас есть экземпляр класса внутри другого класса, вместо того, чтобы наследовать от него
На этой странице есть хорошая статья, объясняющая, почему люди скажите «предпочитать композицию наследованию» с некоторыми примерами того, почему.