Под наследяване се разбира възможността класът наследник да ползва характеристиките (данните и методите) на своите класове-предшественици
- пряка или непряка връзка на наследяване между класовете (базов клас, роди-тел, суперклас, производен клас, внук, правнук, прародител, прадядо и т.н)
- Наследяването представлява отношение на йерархична връзка между класовете
- йерархия на наследяване – съвкупност от класове, обединени от връзки на наследяване
- предаване на информация чрез връзките на наследственост
Видове наследяване
- Семантична класификация (според вида на наследяваните свойства)
- наследяване на части (partnomy) – наследяват се физическите характеристики на класа
- наследяване на поведенчески свойства (taxonomy) – наследяват се функционалните характеристики на класа (Common Objects)
- наследяване и на двата вида характеристики на класа (Object Pascal, C++, Java, Смолток и т.н.)
- Описателна класификация (според броя на възможните класове-предшественици)
- единично (single) наследяване – всеки клас може да има най-много един предшественик
- множественото (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 ще заема голям обем памет. Освен това изпълнението на алгоритъма за свързване изисква допълнително време при изпълнение на програмата.
Няма сходни статии.
