Спадкаваньне (праграмаваньне)

У аб’ектна-арыентаваным праграмаваньні **спадкаваньне** — гэта спосаб стварэньня новых клясаў (экзэмпляры якой называюцца аб’ектамі) выкарыстоўваючы ўжо існуючыя клясы. Новыя клясы, вядомыя як **вытворныя клясы**, пераймаюць (або **спадкуюць**) атрыбуты і паводзіны ўжо існуючых клясаў, якія завуцца **базавымі клясамі** (альбо клясамі-папярэднікамі). Адной з ідэяў такога мэханізма зьяўляецца паўторнае выкарыстаньне існуючага коду шляхам нязначных зьменаў альбо бязь іх.

**Спадкаваньне** часам называюць таксама **абагульненьнем**, таму што герархія паміж клясамі і аб’ектамі можа быць выяўленая ў адносінах тыпу *ёсьць*. Напрыклад, «садавіна» — гэта абагульненьне «яблыка», «апэльсіна», «манга» і шматлікіх іншых. Садавіна можа разглядацца як абстракцыя яблыка, апэльсіна і г. д. Наадварот, улічваючы тое, што яблыкі зьяўляюцца садавінай (то бок, яблык **ёсьць** садавінай), яблыкі, натуральна, могуць спадкаваць усе ўласьцівасьці, агульныя для фруктаў, такія як, напрыклад, зьяўляцца кантэйнэрам зь мякаці, які ўтрымлівае насеньне.

Перавагай спадкаваньня зьяўляецца тое, што модулі з дастаткова падобнымі інтэрфэйсамі могуць падзяляць вялікую колькасьць агульнага коду, што зьмяншае складанасьць праграмы. Таму спадкаваньне мае яшчэ адно прадстаўленьне, якое называецца палімарфізмам. Яно апісвае стан, калі вялікая колькасьць частак коду кантралюецца агульным кіруючым кодам.

## Тыпы спадкаваньня
### Простае спадкаваньне
Простым спадкаваньнем зьяўляецца спадкаваньне, калі нашчадак спадкуе ўласьцівасьці адной сваёй бацькоўскай клясы.

У пэўных мовах выкарыстоўваюцца абстрактныя клясы. *Абстрактная кляса* — гэта кляса, якая ўтрымлівае прынамсі адзін абстрактны мэтад. Абстрактная кляса ня можа выкарыстоўвацца для непасрэднага стварэньня аб’ектаў, то бок ад такой клясы можна толькі спадкаваць. Аб’екты могуць быць створаныя толькі на аснове вытворных клясаў.

### Множнае спадкаваньне

Пры множным спадкаваньні ў клясы можа быць больш за адну бацькоўскую клясу. У гэтым выпадку кляса спадкуе мэтады і палі ўсіх папярэднікаў. Перавагі такога падыходу — у большай унівэрсальнасьці. Множнае спадкаваньне рэалізаванае ў такіх мовах як C++, Python; падтрымліваецца яно мовай UML.

Але множнае спадкаваньне мае свае недахопы. У першую чаргу гэта памылкі, якія ўзьнікаюць, калі бацькоўскія клясы маюць аднолькавыя мэтады. У шэрагу моваў праграмаваньня аўтары адмовіліся ад мэханізму множнага спадкаваньня на карысьць інтэрфэйсаў.

Большасьць сучасных аб’ектна-арыентаваных моваў праграмаваньня (C#, Java, Delphi і іншыя) падтрымліваюць магчымасьць адначасовага спадкаваньня ад клясы-папярэдніцы і рэалізаваньня некалькіх інтэрфэйсаў адной клясай. Гэта дазваляе замяніць множнае спадкаваньне — мэтады інтэрфэйсаў неабходна перавыхначаць наноў, што пазбаўляе ад памылак пры спадкаваньні функцыянальнасьці аднолькавых мэтадаў розных клясаў-папярэднікаў.

## Абмежаваньні і альтэрнатывы
Выкарыстоўваючы спадкаваньне падчас дызайну праграмы, варта не забывацца на пэўныя абмежаваньні, якія яно мае.

Напрыклад, няхай кляса `Асоба` мае такія ўласьцівасьці, як імя, адрас, нумар тэлефона, век, пол і расу. Можна вызначыць падклясу клясы `Асоба`, якую назваць як `Студэнт`, і якая будзе ўтрымліваць сярэдні бал асобы і сьпіс заняткаў, якія яна наведвае. І яшчэ адну падклясу клясы `Асоба`, якая будзе называцца `Супрацоўнік` і будзе ўтрымліваць назву пасады, кіраўніка і велічыню заробку.

Вызначыўшы такія клясы, мы таксама вызначылі і пэўныя абмежаваньні, ня ўсе зь якіх пажаданыя:

### Абмежаваньні праектаваньня з спадкаваньнем
* **Адзінкавасьць**: выкарыстоўваючы простае спадкаваньне, падкляса можа спадкаваць толькі адну бацькоўскую клясу. Працягваючы вышэйзгаданы прыклад, `Асоба` можа быць альбо `Студэнтам`, альбо `Супрацоўнікам`, але не абодвума адразу. Выкарыстаньне множнага спадкаваньня часткова вырашае гэту праблему, бо можна вызначыць клясу `СупрацоўнікСтудэнт`, якая будзе спадкаваць абедзьве клясы `Супрацоўнік` і `Студэнт`. Аднак гэта ўсё роўна дазваляе спадкавацца ад кожнай клясы толькі аднойчы, і таму гэтая схема ня можа выкарыстоўвацца ў выпадках, калі студэнт мае дзьве працы ці наведвае два ўнівэрсытэты.
* **Статычнасьць**: герархія спадкаваньня аб’екта зафіксаваная і вызначаецца толькі аднойчы, калі выбіраецца тып аб’екта, і ня можа быць зьмененая з часам. Такім чынам спадкаваньне не дазваляе аб’екту тыпу `Студэнт` стаць аб’ектам тыпу `Супрацоўнік` з захаваньнем стану сваёй бацькоўскай клясы `Асоба`.
* **Бачнасьць**: калі кліенцкі код мае доступ да аб’екта, звычайна ён мае доступ да зьвестак усіх ягоных бацькоўскіх клясаў. Нават калі бацькоўская кляса не была аб’яўленая публічнай, кліент усё яшчэ можа прывесьці аб’ект да тыпу бацькоўскай клясы. Напрыклад, не існуе спосабу прадаставіць пэўнаму мэтаду доступ да сярэдняга балу аб’екту клясы `Студэнт` без прадастаўленьня гэтаму мэтаду доступу да ўсіх асабістых зьвестак, якія захоўваюцца ў бацькоўскай клясе студэнта `Асоба`.

### Ролі і спадкаваньне
Часам праектаваньне, заснаванае на спадкаваньні, выкарыстоўваецца замест роляў. Роля, напрыклад, **Студэнт** — гэта роля **Асобы** — апісвае характарыстыкі наяўнага аб’екта, таму што аб’ект узаемадзейнічае зь іншым аб’ектам (напрыклад, асоба ў ролі студэнта мусіць наведваць заняткі). Пэўныя мэтады аб’ектна-арыентаванага праектаваньня не адрозьніваюць такога выкарыстаньня роляў ад звычайных аспэктаў аб’ектаў. Але фармуецца тэндэнцыя выкарыстоўваць спадкаваньне для мадэляваньня роляў, скажам нехта будзе мець студэнцкую ролю асобы, змадэляваную як падкляса клясы Асоба. Аднак, ні герархія спадкаваньня, ні тыпы аб’ектаў ня могуць зьмяняцца з часам. Таму мадэляваньне роляў як падклясаў можа выклікаць сытуацыю, калі ролі будуць зафіксаваныя на момант свайго стварэньня. Напрыклад, Асоба ня зможа проста зьмяніць сваю ролю з Студэнта на Супрацоўніка, калі зьменяцца абставіны.

З пункту погляду мадэляваньня такія абмежаваньні часьцяком непажаданыя, таму што яны выклікаюць штучныя абмежаваньні на будучую пашыральнасьць сыстэмы аб’ектаў, што выкліча складанасьці падчас рэалізацыі будучых зьменаў з-за таго, што патрабуецца абнаўленьне бягучай спраектаванай мадэлі.

Катэгорыя:Аб’ектна-арыентаванае праграмаваньне