Наследяване в обектно ориентираното програмиране

Под наследяване се разбира възможността класът наследник да ползва характеристиките (данните и методите) на своите класове-предшественици

  • пряка или непряка връзка на наследяване между класовете (базов клас, роди-тел, суперклас, производен клас, внук, правнук, прародител, прадядо и т.н)
  • Наследяването представлява отношение на йерархична връзка между класовете
  • йерархия на наследяване – съвкупност от класове, обединени от връзки на наследяване
  • предаване на информация чрез връзките на наследственост

Видове наследяване

  • Семантична класификация (според вида на наследяваните свойства)
  • наследяване на части (partnomy) – наследяват се физическите характеристики на класа
  • наследяване на поведенчески свойства (taxonomy) – наследяват се функционалните характеристики на класа (Common Objects)
  • наследяване и на двата вида характеристики на класа (Object Pascal, C++, Java, Смолток и т.н.)
  • Описателна класификация (според броя на възможните класове-предшественици)
  1. единично (single) наследяване – всеки клас може да има най-много един предшественик
  2. множественото (multiple) наследяване - всеки клас може да има произволен брой предшественици (C++, CLOS, Flavors)

Проектиране на йерархия на наследяване

  • Цел при проектиране на йерархията:

Класификация на участващите класове

  • Правила:

1. Категоризирането на обектите и проектът на йерархията на наследяването зависят от предназначението на програмната система (област на приложение, нейните функционални спецификации, изискванията на потребителите и др.), т. е. обективно – от решаваната задача и субективно – от самия проектант.

2. Изграждането на йерархията от класове е последователен итеративен процес

Форми на класификация

  • специализация (генерализация) – наследникът специализира, доуточнява някои от характеристиките на своя предшественик;
  • спецификация – предшественикът определя поведение, което се специфицира в наследника;
  • конструиране – наследникът използва много от методите на предшественика, но по същество се различава от него;
  • обобщение – наследникът е по-обща категория от предшественика;
  • разширение – наследникът добавя нови методи без да променя функционалността на предшественика;
  • ограничение – наследникът ограничава поведението на предшественика, т. е. премахва някои от неговите свойства;
  • вариране – предшественикът и наследникът са различни вариации на една и съща категория. В този случай не е от значение кой е предшественик и кой е наследник;
  • комбиниране – наследникът комбинира свойства от повече от един предшественик. Използва се при множественото наследяване.

Специализацията като форма на наследяване

  • Същност:

Наследяване с цел специализация се постига чрез разграничава-не на класовете по отношение на това – кои от тях са по-общи или по-всеобхватни

  • Правила при пораждане на подклас с цел специализация:
  • новият клас е по-специализирана форма на родителския клас
  • удовлетворява спецификациите на родителския клас във всички съществени моменти
  • всички свойства, приложими за родителския клас са приложими и за неговия наследник
  • всеки екземпляр на подкласа е екземпляр на неговия родител
  • наследникът, от своя страна, може да притежава и някои специфични свойства

Средствата на обектно ориентираното програмиране за реализиране на наследяването

  • Добавяне на нови полета и методи – наследникът дефинира характеристики, които неговият предшественик не притежава (полето Whole и метода GetWhole за TMixed)
  • Чисто наследяване – наследникът използва характеристиките на предшественика, без отново да ги дефинира (полетата Numer, Denom)
  • Предефиниране – характеристиките на предшественика се дефинират отново и от наследника (обикновено по нов начин). В случай на предефиниране на методи е възможно или да се допълни методът на предшественика (уточняване) или той изцяло да се видоизмени (заменяне), т. е. предефинираният метод е модел на същата функционалност, но изразена по друг начин (методите Reduce и Print)
  • Скриване на полета и методи – за наследника някои от характеристиките на предшественика са скрити (недостъпни)

Статично срещу динамично свързване. Рализация на механизма на “къснато” свързване в MS Visual C++virtual function table (v-table), vfptr.

Механизъм на “късно свързване”. Виртуални методи

  • Механизъм на “късно свързване” (МКС) – late binding

Механизъм на “късно свързване” (динамично свърз-ване) е този, при който определянето на версията на даден метод (евентуално предефиниран многократно в йерархията на наследяване), която ще бъде изпъл-нена при получаване на съответното съобщение, се извършва по време на изпълнение на програмата.

  • Виртуални (динамични) методи:

Методи, за които свързването се осъществява по МКС се наричат виртуални (virtual, override), а в някои случаи и динамични методи (dynamic)

  • Правило на МКС:

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

МКС и обработка на екземпляри

  • Реализация на МКС:

–        за да може динамичният тип на реципиента да бъде определен е необходимо поддържането на допълнителна информация за обектите в процеса на изпълнение на програмата

–        операцията инициализация на обекти е в основата на механизма за поддържане на допълнителната информация по време на изпълнение (“run–time”), осигуряващ МКС

  • Правила:

–        Преди да се извърши каквато и да е обработка на обект, който изисква прилагане на МКС, е необходимо той да бъде инициализиран

–        Инициализацията на обект се извършва чрез специално предназначен за тази цел метод

  • Подходи в различните ЕООП:

–        ООЕП с динамичен тип на променливите (Смолток, Objective-C) – операция new, клас-методи, фабрични методи

–        ООЕП със статичен тип на данните (C++, Object Pascal, Java) – метод конструктор

Техническа реализация на МКС

Техническата реализация на МКС при виртуалните методи в С++ е съчетание от три технически решения:

  • представяне на обектовите екземпляри в паметта
  • поддържане на специална таблица в паметта, наречена v-table
  • реализация на специален алгоритъма при свързване на виртуалните методи по МКС
  • Представяне на обектовите екземпляри в паметта – vfptr:
  • записват се последователно (по реда на деклариране) полетата на обекта
  • ако екземплярът е от тип, който наследява друг тип, първо се записват наследените полета, а след това – новите полета
  • когато типът на екземпляра съдържа декларация или наследява виртуални методи, то в паметта, заделена за екземпляра се обособява и едно поле vfptr – указател към таблицата на виртуалните функции (virtual function table). Полето за vfptr се наследява без добавяне на ново

Таблица на виртуалните функции (v-table)

  • Във v-table са записани адресите (входните точки) на виртуалните методи деклариран в класа (по реда на деклариране) или наследени от предшествениците и др. допълнителна информация
  • За всеки клас(а не за всеки екземпляр), които съдържа или наследява виртуални методи, се създава само една v-table
  • v-table не се наследява. Дори когато даден клас наследява друг, за него се създава собствена v-table
  • Адресите на предефинираните виртуални функции в различни класове се записват на една и съща позиция в съответната v-table (ефективен достъп)
  • v-table се създава автоматично и никога не се обработва директно от програмиста. Таблицата се създава при първото активиране на конструктора на класа

Алгоритъма при свързване на виртуалните методи по МКС

  • Когато екземпляр на даден клас активира за първи път конструктора на този тип, то тогава се създава съответната v-table. Когато вече е бил инициализиран друг екземпляр от типа, тази стъпка се пропуска. Адресът на v-table се записва във vfptr на екземпляра
  • При активиране на виртуален метод от този екземпляр чрез vfptr се извлича адресът на v-table на неговия клас
  • От v-table се извлича входната точка на съответния виртуален метод
  • Виртуалният метод се изпълнява

Извод: Както се вижда, v-table на даден клас съдържа по един адрес (входна точка) за всеки виртуален метод, деклариран в типа и във всички негови предшественици. Ако типовете на предшествениците дефинират голям брой виртуални методи, то тази v-table ще заема голям обем памет. Освен това изпълнението на алгоритъма за свързване изисква допълнително време при изпълнение на програмата.

Няма сходни статии.

Responses are currently closed, but you can trackback from your own site.

Comments are closed.

Subscribe to RSS Feed Follow me on Twitter!