Множествено наследяване на Java. Сравнение на състава и наследството

Множествено наследяване на Java

"Диамантен проблем"

Множество наследяване и интерфейси

Композиция като спасение

Състав или наследство?

Да предположим, че имаме следния куп клас родител-дете:

Кодът по-горе се компилира и работи добре, но какво, ако ClassC е внедрен по различен начин:

Обърнете внимание, че методът test () вече съществува в наследения клас, но връща различен тип резултат. Сега ClassD, в случай че използвате IDE, няма да бъде компилиран. Ще бъдете посъветвани да промените типа на връщане в наследения клас или в суперкласа.

Сега нека си представим ситуация, при която има многостепенно наследяване на клас и суперкласът не е наличен за нашите промени. Сега, за да се отървем от грешката при компилацията, нямаме друга възможност освен да сменим подписа или името на метода на подкласа. Също така ще трябва да направим промени на всички места, където е бил извикан този метод. По този начин наследяването прави нашия код крехък.

Описаният по-горе проблем никога не възниква в случай на композиция и следователно прави последния за предпочитане пред наследяването.

Следващият проблем с наследяването е, че излагаме всички методи на родителя на клиента. И ако суперкласът не е проектиран много добре и съдържа дупки в сигурността. Тогава, въпреки факта, че се грижим изцяло за сигурността, когато изпълняваме нашия подклас, ние все още ще разчитаме на погрешното изпълнение на родителския клас.

Композицията ни помага при осигуряването на контролиран достъп до методите на суперкласа, докато наследяването не поддържа никакъв контрол върху неговите методи. Това също е едно от основните предимства на композицията пред наследяването.

Друго предимство на композицията е, че добавя гъвкавост при извикване на методи. Изпълнението на ClassC, описано по-горе, не е оптимално и използва ранно свързване с извикания метод. Минималните промени ще ни позволят да направим извикванията на методи гъвкави и да осигурим късно свързване (обвързване по време на изпълнение).

Горната програма ще покаже:

Тази гъвкавост при извикване на метод не се вижда при наследяване, което налага композицията като най-добрият подход.

Единичното тестване е по-лесно в случая на композицията, тъй като знаем, че за всички методи, които се използват в суперкласа, можем да поставим мъниче за тестове, докато при наследяването сме силно зависими от суперкласа и не знаем как методите на ще се използва родителският клас. По този начин, поради наследяването, трябва да тестваме всички методи на суперкласа, което е излишна работа.

В идеалния случай наследяването трябва да се използва само когато връзката "is-a" е вярна за класовете родител и дете, в противен случай се предпочита композицията.