Наслеђивање је када објекат или класа базира на другом објекту (прототипско програмирање) или класи (класно-оријентисано програмирање), користећи исту имплементацију (наслеђену од објекта или класе), специфирајући имплементацију да се понаша исто (интерфејсинг; наслеђено понашање). То је механизам за поновно коришћење кода који омогућава независност екстензије од оригиналног софтвера помоћу класа и интерфејса. Однос објеката или класа током наслеђивања је допринео развоју хијерархије. Наслеђивање је осмишљено 1967, у Симули.
Наслеђивање не би требало да буде конфузно са подтипом.Cardelli, Luca (1993). У неким језицима се наслеђивање и подтипови слажу,док су у неким програмским језицима различити; генерално подтип успоставља је-a релацију, док наслеђивање само поново користи имплементацију и успоставља синтаксичку равнотежу, не стално и семантичку (Наслеђивање не гарантује подтипско понашање). Да бисмо разликовали ове концепте, кажемо и да је сабтајпинг познат и као интерфејсно наслеђивање, док је наслеђивање описано као наслеђивање имплементација или наслеђивање кода. Наслеђивање је најчешће коришћен механизам за успостављање равнотеже подтипских релација.
Наслеђивање чини објектна композиција, где један објекат садржи други објекат (или објекат једне класе садржи објекат друге класе), види композицију преко наслеђивања. Композиције имплементирају има-a равнотежу, што је супротно од равнотеже коју успоставља подтип (је-a).
Типови наслеђивања мини|Једноструко наслеђивање мини|Вишесложно и вишеструко наслеђивање Постоје различити типови наслеђивања,. базираних на парадигмалном и специфичном програмирању. Једноструко наслеђивање Када подкласа наслеђује особине једне супер класе. Класа добија особине друге класе.
Вишеструко наслеђивање Када једна класа може да има више родитељских класа и наслеђује особине свих родитељских класа.
Вишесложно наслеђивање : када је подкласа наслеђена од друге подкласе. Није неуобичајено да је класа изведена од друге изведене класе као што и сам наслов говори "Вишесложно наслеђивање". Класа А је база за изведену класу B, док је класа B база за изведену класу C. За класу B се каже да је средња база-класа јер представља везу за наслеђивање између класе А и класе C. Ланац ABC се још назива и путања наслеђивања.
Изведена класа вишесложног наслеђивања:Class A(...); //Родитељска класа Class B : public A(...); //B изведена из A Class C : public B(...); //C изведена BОвај процес се може проширити на вишебројни ниво. Хијерархијско наслеђивање када је једна класа-суперкласа (базна класа) за више подкласа. Хибридно наслеђивање од два или више типа наслеђивања.
Подкласе и суперкласе Подкласа, изведена класа, дечија класа, је модуларна , дериватна класа која наслеђује једно или више језичких ентитета од једне или више других класа (суперкласа, базна класа, родитељска класа). Семантика наслеђивања класе варира од програма до програма, али углавном подкласе аутоматски наслеђују варијабле и чланове функција из суперкласе. Општи облик дефинисања изведене класе је: class derived-class-name : visibility-mode base-class-name { .....// .....// чланови изведене класе .....// }; Двотачка означава да је изведена класа име, изведена из базне класе име. Видљивост је опционална и може бити скривена или јавна. Произвољно изабрани мод је скривен. Видљивост карактерише базну класу скривено или јавно.
Неки програми подржавају наслеђивање и других конструкција. Нпр. у Ајфелу, „уговор“ који карактерише спецификацију класа, карактерише и наследнике. Суперкласа омогућава заједнички приступ и оснивачку функционалност, што доводи до тога да подкласе могу да наслеђују, модификују и суплементирају. Софтверско наслеђивање уз помоћ подкласа је поново коришћено у подкласама. Референца инстанце класе може се односити на неку од њених подкласа. Стварну класу објеката која је референцована, тешко је предвидети у преведено време. Јединствени приступ се користи да се позову чланови функције броја објеката других класа. Подкласа може да замени функције суперкласе са потпуно новим функцијама које морају да имају исту методу.
Ненаследне класе У неким програмима класа може бити означена као ненаследна, додајући класне модификаторе у опис класе. Примери укључују финалну кључну реч у Јави или заглављену кључну реч у C#. Такви модификатори су додати у класној декларацији пре класне кључне речи и класног проналазача декларације. Тако заглављене класе имају ограничену употребљивост, када једино девелопери имају приступ реорганизованом бинарном фајлу или изворном коду.
Заглављена класа нема подлкасе, тако да може бити одбијена у сложеном времену, тако да су референце или показивачки објекта класе референцне инстанце класа али не и инстанце подкласа (које не постоје) или инстанце суперкласа. Подтипски полиморфизам. Зато што је тачан тип објекта био референцован пре извршења,рано везивање (статично обавештење) може бити коришћено уместо касног везивања (још познато и као „динамично обавештење), која подразумева једну или више виртуалних метода табела, чији изглед зависи од тога да ли програм подржава вишесложно наслеђивање или једносложно наслеђивање.
Методе које не могу бити прескочене Класе могу бити затворене/завршене, декларација метода може да садржи модификатор метода који спречава да се метод прескочи (и.е. заменити новом функцијом са истим именом и типом у подкласи). Скривен метод је веома једноставан зато што није доступан другим класа осим класи која је члан функције (ово није тачно у C++). Финална метода у Јави, скривена метода у C# или залеђена особина у Ајфелу не могу бити прескочене.
Виртуалне методе Ако је метода суперкласе виртуална метода, призивање суперкласних метода ће бити динамично послато. Неки програми подразумевају да методе буду специфично декларисано као виртуалне (нпр. C++) у неким програмима све методе су виртуалне (нпр. Јава). Позиви не-виртуалне методе ће бити увек статички послате (адреса позива функције се налази у сложеном-времену). Статично слање је брже од динамичког и садржи оптимизам који се назива стаза за проширење.
Видљивост наслеђених чланова Base class
видљивостВидљивост изведене класе Јавна
деривацијаПриватна
деривацијаОсигурана
деривација Скривена → Осигурана → Јавна → Ненаслеђена Осигурана Јавна Ненаслеђена приватна приватна Ненаслеђена Осигурана Осигурана
Апликације Апликације се користе да две или више класе умреже. Прелазак преко Многи објектно-оријентисани програмски језици допуштају класи или објекту да замене имплементацију једног аспекта-у главном понашање-које је наследио. Овај процес се често зове прелазак преко. Прелазак преко захтева компилацију: која верзија понашања има инстанцу наслеђене класе-део те дате класе или део из родитељске (базне) класе? Одговор варира у зависности од програмског језика, док су неки језици развили способност да покажу да партикуларно понашање неће бити пређено и да треба да се понаша као што је дефинисано од стране родитељске класе. На пример, у C#, базне методе могу бити пређене само у подкласи ако су означене виртуалном, апстрактном или пређи преко модификатором.override(C# Reference) Алтернатива за прелазак преко јескривање наслеђеног кода. Поновна употреба кодаНаслеђивање имплементације је механизам којим подкласа поново користи код у родитељској класи. Подкласа садржи све операције родитељске класе, али подкласа може прећи преко неких или свих операција , замењујући имплементацију родитељске класе, својом имплементацијом.
У пратећем Пајтоновом примеру, подкласа CubeSumComputer прегазила је transform() методу родитељске класе SquareSumComputer. Родитељска класа садржи операције за израчунавање суме корена између два броја. Подкласа користи све функције родитељске класе са изузетком операције која трансформише број у квадрат тог броја, та функција је замењена операцијом која трансформише број у куб. Подкласа израчунава суму кубова између два броја.class SquareSumComputer(object): def __init__(self, a, b): self.a = a self.b = b
def transform(self, x): return x * x
def inputs(self): return range(self.a, self.b)
def compute(self): return sum(self.transform(value) for value in self.inputs())
class CubeSumComputer(SquareSumComputer): def transform(self, x): return x * x * xУ већини квартала, класно наслеђивање има једину намену у виду реупотребе. Примарна брига је та што наслеђена имплементација не обезбеђује уверење у полиморфну заменску моћ- инстанца поновне употребе класе не може неминовно бити замењена за инстанцу наслеђене класе. Алтернативни начин, делегација, захтева већи напор од стране програма, али избегава питање замене. У C++ скривено наслеђивање може бити коришћено у форми наслеђене имплементације без замене. Док јавно наслеђивање представља је-а везу и делегација представља има-a везу, скривено (и осигурано) наслеђивање се може посматрати као веза јесте имплементирано у зависности од Још једно често коришћење наслеђивања јесте да би се гарантовало да класе одржавају одређени заједнички приступ; тј. да имплементирају исте методе. Родитељска класа може бити комбинација имплементираних операција и операција које су имплементиране у дечијим класама. Често, не постоји приступ промене између два подтипа и под типа - понашање дечије имплементације је описано њеном родитељском класом.
Наслеђивање против подтипова Наслеђивање је слично али и различито од подтипског полиморфизма. Подтип омогућава да дати тип буде замењен за други тип или апстракцију, и речено је већ да успоставља "је-а" релацију између подтипа и неке постојеће апстракције, имплицитно или експлицитно, у зависности од програма. Релација се може представити експлицитно уз помоћ наслеђивања у програмима који подржавају наслеђивање као механизам подтипа. На пример, код у C++ успоставља експлицитну релацију наслеђивања између класа B и A, где је B и подкласа и подтип од А, и може бити коришћен као А кад год је B одређено ( уз помоћ референци, индикатора или сопственог објекта)class A { public: void DoSomethingALike() const {}
class B : public A { public: void DoSomethingBLike() const {}
void UseAnA(A const& some_A) { some_A.DoSomethingALike(); }
void SomeFunc() { B b; UseAnA(b); // b може бити замењено са A. }У програмима који не подржавају наслеђивање као подитпски механизам, релација између базне класе и изведене класе је једино релација између имплементација (механизам за поновну употребу кода), упоредно релацији између типова. Наслеђивање, чак и у програмским језицима који подржавају наслеђивање као механизам подтипова, не мора нужно захтевати подтипско понашање. У потпуности је могуће извести класу чији ће се објекат понашати лоше када је коришћен у контексту где је очекивана родитељска класа; видети Лисков принцип замене.
Дизајнирана ограничења Коришћење наслеђивања екстензивно у дизајнирању програма намеће нека ограничења.
На пример, размотримо класу Person која садржи име особе, датум рођења, адресу и број телефона. Можемо дефинисати подкласу класе Person и назвати је Student која садржи просек оцена из класе Person, и другу подкласу класе Person коју називамо Employee која садржи наслов посла, запослене и плату из класе Person.
У дефинисању ове хијерархије наслеђивања, већ смо дефинисали нека ограничења, али не сва ограничења која су неопходна: Усамљеност Користећи једно наслеђивање, подкласа може наследити од само једне суперкласе. Настављајући горенаведени пример, Person класа може бити или Student или Employee, али не оба. Користећи мултипликативно наслеђивање при парцијалном решавању овог проблема, као један се може дефинисати StudentEmployee класа која наслеђује из обе класе Student и Employee. У већини имплементација, се само једном може наследити из сваке суперкласе, и то тако, да не подржава случајеве када студент има два посла или похађа две институције. Модел наслеђивања доступан у Ајфелу чини ово могућим кроз подршку за понављачко наслеђивање.
Статичност