Аб’ектна-арыентаванае праграмаваньне

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

## Разьвіцьцё
Аб’ектна-арыентаванае праграмаваньне сягае сваімі каранямі ў 1960-я — час, на які прыйшоўся крызіс праграмнага забесьпячэньня, які заключаўся ў тым, што ў той час паўстала пытаньне: апаратнае й праграмнае забесьпячэньне робіцца ўсё больш складаным, як пры гэтым можна захаваць якасьць праграмаў? Гэтая праблема разьвязваецца пры дапамозе аб’ектна-арыентаванага праграмаваньня ўвядзеньнем модульнасьці ў праграмнае забесьпячэньне.

Першай мовай праграмаваньня, дзе зьявіліся канцэпцыі, на якіх грунтуецца аб’ектна-арыентаванае праграмаваньне (аб’екты, клясы, падклясы, віртуальныя мэтады, сапраграмы, прыбіраньне сьмецьця й мадэляваньне асобных падзеяў), была Simula як пашырэньне мовы Algol. Першай мовай праграмаваньня, якая атрымала назву «аб’ектна-арыентаваная», была Smalltalk.

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

Тым ня менш, на сёньняшні дзень няма дасьледваньняў, якія б даказвалі, што аб’ектна-арыентаванае праграмаваньне аб’ектыўна лепшае, чым іншыя падыходы.

## Фундамэнтальныя паняткі
Дэбара Армстранґ () правяла дасьледваньне кампутарнай літаратуры, якая выдавалася цягам апошніх 40 гадоў. У выніку гэтага дасьледваньня атрымалася вылучыць фундамэнтальныя паняткі, якія выкарыстоўваюцца ў пераважнай большасьці азначэньняў аб’ектна-арыентаванага праграмаваньня. Да іх належаць:

; Кляса

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

; Аб’ект

: Канкрэтны экзэмпляр клясы. Кляса `Сабака` адпавядае ўсім сабакам шляхам апісаньня іх супольных рысаў; аб’ект `Лэсьсі` — гэта пэўны сабака, з пэўным варыянтам значэньняў характарыстык. `Сабака` мае футра; `Лэсьсі` мае карычнева-белае футра. На жаргоне праграмістаў аб’ект `Лэсьсі` зьяўляецца **экзэмплярам** клясы `Сабака`. Мноства значэньняў атрыбутаў пэўнай клясы называецца станам клясы.

; Мэтад

: Магчымасьці аб’екта. Паколькі `Лэсьсі` — сабака, яна мае здольнасьць гаўкаць. Таму гаўкаць() зьяўляецца адным з мэтадаў аб’екту `Лэсьсі`. Ён можа мець і іншыя мэтады, напрыклад `сядзець()` або `есьці()`. У праграме выкарыстаньне мэтада павінна ўплываць толькі на адзін аб’ект; усе `Сабака` могуць гаўкаць, але трэба, каб гаўкаў толькі адзін пэўны сабака.

; Абмен паведамленьнямі

: «Працэс перадачы дадзеных ад аднаго працэса іншаму, або дасыланьня іншаму запытаў на выкананьне мэтадаў».

; Спадкаваньне

: У некаторых выпадках кляса таксама можа мець «падклясы» — больш спэцыялізаваныя вэрсіі клясаў. Напрыклад, кляса `Сабака` можа мець падклясы `Кольлі`, `Чыхуахуа` й `ЁркшырскіТэр'ер`. У гэтым выпадку `Лэсьсі` будзе экзэмплярам падклясы `Кольлі`. Падклясы спадкуюць атрыбуты й паводзіны сваіх бацькоўскіх клясаў, а таксама могуць мець свае ўласныя. Няхай кляса `Сабака` мае мэтад `гаўкаць()` і ўласьцівасьць `колерФутра`. Кожная з гэтых падклясаў (`Кольлі`, `Чыхуахуа` й `ЁркшырскіТэр'ер`) будзе спадкаваць гэтыя члены, а гэта азначае, што код для іх праграмісту трэба напісаць толькі адзін раз. Кожная падкляса можа зьмяніць свае спадкаваныя прыкметы. Напрыклад, кляса `Кольлі` можа вызначыць, што значэньнем па змоўчаньні ўласьцівасьці `колерФутра` будзе карычнева-белы. `Чыхуахуа` можа вызначыць мэтад `гаўкаць()` як пранізьлівы па змоўчаньні. Падклясы могуць таксама дадаваць новых членаў. Напрыклад, падкляса `Чыхуахуа` можа дадаць мэтад `дрыжэць()`. Такім чынам, асобны экзэмпляр чыхуахуа можа выкарыстоўваць `гаўкаць()` прынізьліва ад падклясы `Чыхуахуа`, які ў сваю чаргу спадкуе звычайнае `гаўкаць()` ад `Сабака`. Аб’ект `Чыхуахуа`  таксама будзе мець мэтад `дрыжэць()`, але ў `Лэсьсі` такога мэтада ня будзе, бо `Лэсьсі` — гэта `Кольлі`, а не `Чыхуахуа`. Спадкаваньне ўводзіць адносіны «ёсьць»: `Лэсьсі` ёсьць `Кольлі`, `Кольлі` ёсьць `Сабака`. Таму `Лэсьсі` спадкуе ўласьцівасьці абедзьвюх клясаў: `Кольлі` й `Сабака`. Калі аб’ект ці кляса спадкуе ўласьцівасьці ад больш чым адной продкавай клясы, і ніводны з гэтых продкаў не зьяўляецца продкам іншага, тады гэта называецца множным спадкаваньнем. Напрыклад, могуць быць вызначаныя незалежныя клясы `Сабака` й `Кот`, але зь іх будзе створаны аб’ект `[[Хімэра]]`, які спадкуе паводзіны й сабакі, і ката. Але гэтая магчымасьць падтрымліваецца не заўсёды, бо можа быць дастаткова цяжка рэалізаваць і пасьля выкарыстоўваць тое, што атрымаецца.

; Інкапсуляцыя

: Хаваньне дэталяў, як працуе пэўная кляса, ад аб’ектаў, якія яе выкарыстоўваюць або адпраўляюць ёй паведамленьні. Так, напрыклад, кляса `Сабака` мае мэтад `гаўкаць()`. Рэалізацыя гэтага мэтада апісвае, як мусіць адбывацца гаўканьне (напрыклад, спачатку `удыхнуць()`, а пасьля `выдыхнуць()` на выбранай частаце й гучнасьці). Пятро, гаспадар `Лэсьсі`, не павінен ведаць, як яна гаўкае. Інкапсуляцыя дасягаецца шляхам пазначэньня, як клясы могуць зьвяртацца да членаў аб’екта. Як вынік, кожны аб’ект прадастаўляе любой клясе пэўны інтэрфэйс — члены клясы даступныя іншым клясам. Інкапсуляцыя патрэбная для таго, каб прадухіліць выкарыстаньне кліентамі інтэрфэйсу тых частак, якія, хутчэй за ўсё, будуць зьмененыя. Гэта дазволіць палегчыць унясеньне зьменаў, бо для гэтага ня будзе патрэбы зьмяняць карыстальнікаў інтэрфэйсу. Напрыклад, інтэрфэйс можа гарантаваць, што шчаняты могуць дадавацца да аб’ектаў клясы `Сабака` толькі кодам самой клясы. Часта члены клясы пазначаюцца як **агульны** (анг. *public*), **абаронены** (анг. *protected*) й **асабісты** (анг. *private*), вызначаючы, даступныя яны ўсім клясам, падклясам ці толькі клясе, у якой яны вызначаныя адпаведна. Пэўныя мовы праграмаваньня ідуць яшчэ далей: Java выкарыстоўвае ключавое слова **protected** для абмежаваньне доступу, які будзе дазволены таксама з клясаў з таго ж пакета, C# і VB.NET абмяжоўваюць выкарыстаньне пэўных членаў толькі клясамі з той жа зборкі выкарыстоўваючы ключавыя словы **internal** (C#) або **Friend** (VB.NET), а Eiffel і C++ увогуле дазваляюць пазначаць, якія клясы могуць атрымаць доступ да любога члена.

; Абстрагаваньне

: Спрашчэньне складанай рэчаіснасьці шляхам мадэляваньня клясаў, якія падыходзяць для разьвязаньня праблемы, і работа на ўзроўні дэталізацыі, які найлепшым чынам падыходзіць для разьвязаньня акрэсьленых аспэктаў праблемы. Напрыклад `Сабака` `Лэсьсі` большую частку часу можа разглядацца як `Сабака`, калі патрэбна атрымаць інфармацыю, спэцыфічную для сабак пароды кольлі, — як `Кольлі` і як `Жывёла` (магчыма, бацькоўская кляса для клясы `Сабака`) для пераліку хатніх жывёлаў Пятра.

; Палімарфізм

: Палімарфізм — здольнасьць клясы выкарыстоўваць паводзіны ў залежнасьці ад умоваў, у якіх гэтыя паводзіны патрабуюцца, то бок два ці большая колькасьць клясаў могуць рэагаваць па-рознаму на аднолькавыя паведамленьні. Напрыклад, калі `Сабака` атрымлівае каманду `голас()`, то ў адказ можна атрымаць `Гаў`; а калі `Сьвіньня` атрымлівае каманду `голас()`, то ў адказ можна атрымаць `Рох`. Гэтыя паводзіны й чакаюцца, таму што `Сьвіньня` мае канкрэтную рэалізацыю мэтада `голас()`. Тое самае адбываецца з клясай `Сабака`. Улічваючы, што абодва зь іх спадкуюць `голас()` ад `Жывёла`, гэта прыклад перавызначальнага палімарфізму.

### Прататыпна-арыентаванае праграмаваньне

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

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

; Палі зьвестак: Парамэтры аб’екта, якія неабходныя праграме й якія задаюць стан аб’екта (уласьцівасьці аб’екта прадметнай вобласьці). Часам узьнікае блытаніна, калі палі зьвестак аб’екта называюць ягонымі ўласьцівасьцямі.

; Мэтады: Дзеяньні, якія можна выконваць з аб’ектам тагога тыпу або якія можа выконваць сам аб’ект.

; Уласьцівасьці: Значэньні, якія даступныя на чытаньне й/альбо запіс праз мэтады, якія называюцца аксэсарамі (ад анг. *access* — доступ). Гэтыя мэтады звычайна называюцца гетэрамі (чытаньне) й сэтэрамі (запіс). Яны забясьпечваюць чытаньне й вызначэньне значэньняў палёў дадзеных, зьвязаных з уласьцівасьцямі. Уласьцівасьці можна разглядаць як «разумныя» палі дадзеных, якія суправаджаюць доступ да поля дадзеных якімі-небудзь дадатковымі дзеяньнямі (напрыклад, перамылёўка аб’екта пры зьмене ягоных каардынатаў).

## Канцэптуальны падыход
Кожны *аб’ект* зьяўляецца экзэмплярам пэўнай **[[кляса (праграмаваньне)|клясы]]**. Адна кляса адрозьніваецца ад іншай імем і, звычайна, наборам інтэрфэйсаў, якія падтрымліваюцца. Інтэрфэйсы, у сваю чаргу, зьяўляюцца наборам паведамленьняў, якія можна адпраўляць аб’екту.

## Крытыка
* Дасьледваньне Томаса Потака ды інш. паказала адсутнасьць значнай розьніцы ў прадуктыўнасьці распрацоўкі праграмнага забесьпячэньня паміж аб’ектна-арыентаваным праграмаваньнем і працэдурным падыходам.
* Крыстафэр Дэйт паказвае на немагчымасьць параўнаньня аб’ектна-арыентаванага праграмаваньня й іншых тэхналёгіяў пераважна з-за таго, што адсутнічае строгае й агульнапрынятае вызначэньне аб’ектна-арыентаванага праграмаваньня.
* Аляксандар Сьцяпанаў высунуў ідэю, што аб’ектна-арыентаванае праграмаваньне абмежаванае матэматычнай мадэльлю й зьяўляецца, па сутнасьці, такой самай містыфікацыяй, як і штучны інтэлект.
* Фрэдэрык Брукс у артыкуле *No Silver Bullet. Essence and Accidents of Software Engineering* (*Computer Magazine*; красавік 1987) заўважае, што найбольш складанай часткай стварэньня праграмнага забесьпячэньня зьяўляецца «…спэцыфікацыя, дызайн і тэставаньне канцэптуальных канструкцыяў, а зусім ня праца па рэалізацыі гэтых канцэптуальных канструкцыяў…». Аб’ектна-арыентаванае праграмаваньне, на ягоную думку, ня можа зьнізіць складанасьць распрацоўкі праграмных сыстэмаў. Па ягоным меркаваньні «…аб’ектна-арыентаванае праграмаваньне дазваляе спрасьціць толькі прыўнесеную складанасьць у рэалізацыі дызайна. Дызайн застаецца складаным па сваёй прыродзе…».

## Крыніцы