Книга е още в много ранна фаза на написване


Повторно използване на код



страница10/73
Дата25.07.2016
Размер13.53 Mb.
#6732
1   ...   6   7   8   9   10   11   12   13   ...   73

Повторно използване на код


След като един клас е написан и изпробван тойще представлява (в идеалния случай) полезно късче код. Това изважда наяве че написването на класа изисква опит и познаване на въпроса каквито не всеки има. Веднъж направили го обаче, то плаче да бъде използувано повторно. Повторното използуване на код е най-мощ­ния лост, който ООП предоставя.

Най-простия начин за повторно използуване на код е прякото използуване на обекта, но също може този обект да се постави в друг обект. Наричаме това "съз­даване на член-обект". Новият клас може да се дъздаде от каквито и да са ти­пове обекти, толкова, колкото са необходими за да се получи необходимото по­ведение. Тази концепция е наречена композиция, доколкото се композира нов клас от съществуващи класове. Понякога това се нарича “има” зависимост, как­то в “колата има багажник”.

Композицията дава мтого гъвкавост. Член-обектиге в новия клас са обик­но­ве­но private и това не дава възможност да се използуват направо от потребителя. То­ва дава възможност да бъдат променяни без да се променя клиентския код. Мо­же да променяте също много обекти по време на изпълнение, което дава го­ля­ма гъвкавост. Наследяването, което ще се опише малко по-късно, не дава та­ка­ва гъвкавост, понеже има ограничения въху класовете.

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


Наследяване:
повторно използване на интерфейса


Самата концепция за обекте удобен инструмент. Тя позволява да се пакетират данни и код според концепция, така че може да представите идеята с езика на проблемното пространство, а не с идиомите на подлежащата машина. Тези концепции са изразени в първичната идея за даннов тип (използвайки ключовата дума class).

Би било жалко, обаче, да се създаде някакъв тип и после да трябва да се създава нов с подобна функционалност. Би било по-добре ако може да вземем съ­ще­ству­ващ тип, да го клонираме и да придадем нужните свойства на клонинга. То­ва е, което фактически се получава с наследяването, с това изключение, че ори­ги­налният клас (наречен базов или супер или родителски клас) е променен, про­мененият “клонинг” (наречен извлечен или извлечен или под- или дъщерен клас) също отразява помените. Наследяването се прилага в Java с ключовата ду­ма extends. Когато правите нов клас казвате че той extends съществуващ клас.

Чрез извличане се създава нов тип, който не само всички членове на наследения клас (макар и тези които са private да са скрити и недостъпни), но - което е по-важ­но - повтаря интерфейса на базовия клас. Това значи, че всички съобщения, кои­то се разбират от базовия клас се разбират и от извлечения. Тъй като типа на класа е известен от съобщенията, които той разбира, извлечения клас е от съ­щия тип като базовия клас. Тази еквивалентност на типовете чрез интер­фей­сите им е главния вход към разбирането на ООП.

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

Има два пътя да направите извлечения клас различен от този, който се на­сле­дя­ва. Първият е много праволинеен: просто пишете нови функции в новия клас. Те­зи нови функции не са част от интерфейса на базовия клас. Значи ако ба­зо­вият клас не прави всичко, което искате, просто добавяте необходимото в но­вия клас. Тази примитивна употреба за интерфейс понякога е най-добрия начин да се реши проблем. Трябва да се погледне, обаче, по-отблизо възможността ба­зовия клас да се нуждае от тези функции.

Подтискане на функциите на базовия клас


Въпраки че extends предполага, че ще се добавят нови функции, това не е не­пре­менно вярно. Другия начин да се направи втория клас различен е да се про­мени поведението на съществуваща функция на базовия клас. Това се означава с подтискане на функцията.

За да се подтисне функцията просто се дава нова дефиниция за нея в новия клас. Казваме: “Използвам същата интерфейсна функция, но искам да прави не­що различно.”


Отношенията "е" и "прилича на"


Може да възникне известен дебат относно интерфейса: наследяването да под­тис­ка ли само функциите на базовия клас? Това значи че извлеченият тип е точ­но същия като на базовия клас, защото има същия интерфейс. Като ре­зул­тат обект от единия клас може да замести обект от другия клас. Това може да се на­рече чиста субституция. По усещане това е идеалният начин да се третира на­следяването. Често се казва че отношението между базовия клас и извле­че­ния клас в този случай е е, понеже може да се каже “кръгът е фигура.” Пробата за уместност на наследяването е дали може да се прокара е отношение между два­та класа и да му се придаде смисъл.

Има случаи, когато се налага да се добави интерфейс в извлечения тип и по то­зи начин да се получи нов тип. Новият тип все още може да замества базовия, но работата не изглежда наред, защото стария тип не може да използва новите функ­ции. Това може да се опише като отношение е подобен на; новия тип има интер­фейса на стария, но има и нови функции и не може да се каже, че е точно съ­щия. Например един климатик. Да допуснем, че в къщи всичко е нагласено да се управлява охлаждането, т.е. има интерфейс на охлаждането. Да допуснем че кли­матикът се е развалил и сте го заменили с топлинна помпа, която може да топли и охлажда. Помпата е подобна на климатика, но може повече. Понеже е про­карано управление само за охлаждането, може да се управлява само тази ча­ст на новия обект. Интерфейсът на новия обект е бил разширен и системата не знае за това.

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




Сподели с приятели:
1   ...   6   7   8   9   10   11   12   13   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница