Что такое наследование, композиция и агрегация
Наследование, композиция и агрегация - это способы взаимодействия классов между собой. Т.е. как один класс может использовать методы другого класса.
Композиция и Агрегация является подвидом Ассоциации. Звучит, не понятно, но не все так сложно...
Для, того чтобы было более понятно, я организую всю эту структуру в такой список:
- Способы взаимодействия классов
Уже попроще, т.к. понятна структура терминов. Теперь давайте разберемся с каждым по отдельности.
Наследование
Это один из принципов ООП, который подразумевает, что класс наследник, будет иметь все те же свойства и методы, что и в базовом классе. В коде это выглядит так:
class A {
public function helloWorld() {
echo 'Hello, World!';
}
}
class B extends A {}
$obj = new B();
$obj->helloWorld(); // Hello, World!
Т.е. класс B - наследник класса A. Ему достался метод helloWorld, который он может вызвать сразу или переопределить, а потом вызвать.
Как следует из ключевого слова extend, используется для расширения возможностей базового класса. Со стороны программиста, это может потребоваться для переопределения какого-либо метода или для добавления какой-нибудь новой логики.
Это классика ООП, поэтому думаю с понимаем проблем не должно быть.
Ассоциация
Ассоциация, как следует из названия, это способ взаимодействия, когда один класс ассоциируется с другим. Т.е. один класс использует внутри своей реализации свойства или методы объекта другого класса. Просто запомните, что в отличии от наследования, ассоциации не РАСШИРЯЮТ класс, а ИСПОЛЬЗУЮТ объект другого класса. Дальше мы это увидим на примерах, а пока надо упомянуть, что ассоциации бывают двух видов: Композиция и Агрегация.
- Композиция
Это ассоциация, при которой используемый объект создается внутри класса. Простой пример:
class A {
public function helloWorld() {
echo 'Hello, World!';
}
}
class B {
protected $a;
public function __construct() {
$this->a = new A(); // создает объект другого класса
}
public function sayHello() {
$this->a->helloWorld(); // использует объект другого класса
}
}
$obj = new B();
$obj->sayHello(); // Hello, World!
Тут мы видим, что в конструкторе класса B, создается объект класса A. И дальше используется в методе sayHello. Композиция - это по сути включение класса, внутрь другого класса с помощью создания объекта внутри этого класса.
У такого подхода есть один огромный недостаток - сильная связанность, это значит, что для того чтобы поменять класс A на A1 вам придется переписывать конструктор (new A1 вместо A). Преимущество у такого способа, это то, что класс B управляет временем жизни объекта A. Т.е. при удалении объекта B будет и удален объект A, который был создан внутри B.
- Агрегация
Это ассоциация, при которой используемый объект создается вне класса. Простой пример:
class A {
public function helloWorld() {
echo 'Hello, World!';
}
}
class B {
protected $a;
public function __construct($a) {
$this->a = $a;
}
public function sayHello() {
$this->a->helloWorld(); // использует объект другого класса
}
}
$objA = new A(); // создает объект другого класса
$objB = new B($objA);
$objB->sayHello(); // Hello, World!
Тут мы видим, что создается объект класса A, а затем он передается извне в конструктор класса B. И дальше используется в методе sayHello. Агрегация - это по сути включение класса, внутрь другого класса с помощью передачи объекта внутрь этого класса.
В отличие от композиции, тут все наоборот. Преимущество: легко передать новый объект A1 без изменений в коде - слабая связанность. Из недостатков, пожалуй, следует отметить, что в больших системах это приводит к огромному количеству переменных в конструкторе.
Заключение
Подведем итоги по способам взаимодействия классов:
Наследование - класс наследует поля и методы родительского класса.
Ассоциация:
- Композиция - класс создает объект другого класса внутри себя и использует его поля и методы.
- Агрегация - класс получает объект другого класса извне и использует его поля и методы.