Каква е разликата между наследяване и композиция в Java

Въпреки че както композицията, така и наследяването позволяват повторно използване на кода, те го правят по различни начини. Основната разлика между двете е, че композицията позволява кодът да се използва повторно, без да се разширява. Наследяването обаче изисква разширяване на съществуващия клас. Друга важна разлика е, че с композицията можем да използваме повторно код дори от финален клас, докато е невъзможно да наследим от него. Освен това при композиране е възможно да се използва код от няколко различни класа. Този трик няма да работи с наследяване: Java не поддържа множествено наследяване. Но можете да го направите в C++. Между другото, винаги трябва да предпочитате композицията пред наследяването в Java. И не само защото Джошуа Блох съветва това в книгата си Effective Java (която е чудесен източник на полезни съвети за Java програмист). Можете да прочетете аргументите за използването на композиция тук.

Наследяване и композиция

Нека разгледаме по-отблизо разликите между състава и наследяването. Ще разгледаме всеки артикул достатъчно подробно, но без скучни подробности.

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

Ограничено повторно използване на код при наследяване

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

Заключителни класове

Невъзможността за разширяване на крайните класове е друго ограничение на наследяването. В Java няма начин да се наследи от крайните класове, така че отново единственият изход е да се използва композиция за повторно използване на код.

Капсулиране

Последната разлика между композицията и наследяването в Java е връзката им с капсулирането. Докато и двете техники позволяват повторно използване на кода, наследяването нарушава принципа на капсулиране, тъй като подкласът зависи от поведението на родителския клас. Ако родителски клас промени поведението си, това ще засегне и неговите деца. Ако класовете са лошо документирани и дъщерният клас не използва правилно родителския клас, тогава всяка промяна в родителя ще наруши функционалността на дъщерния клас. За да видите това с пример, можете да прочетете глави 16 и 17 на Ефективна Java.

Това е всичко, което може да се каже за разликите между композицията и наследяването в Java и в обектно-ориентираното програмиране като цяло. Както можете да видите, те служат на една и съща цел по различни начини: повторно използване на изпитани и тествани части от кода. Композицията обаче ви позволява да защитите клас за многократна употреба от клиенти, докато наследяването не гарантира това. Въпреки това, понякога е необходимо наследяване. Особено когато създавате класове от едно и също семейство.