• Co je OOP s příklady. Pro figuríny. Videokurz: Základy objektově orientovaného programování

    Paradigmata programování

    Objektově orientované programování (OOP)- metodologie programování založená na reprezentaci programu jako množiny objektů, z nichž každý je instancí určité třídy a třídy tvoří hierarchii dědičnosti.

    Je třeba věnovat pozornost následujícím důležitým částem této definice: 1) objektově orientované programování používá jako základní logické konstrukce spíše objekty než algoritmy; 2) každý objekt je instancí určité třídy; 3) třídy tvoří hierarchie. Program je považován za objektově orientovaný pouze tehdy, jsou-li splněny všechny tři tyto požadavky. Zejména programování, které nepoužívá dědičnost, se nenazývá objektově orientované programování, ale programování s abstraktními datovými typy.

    Encyklopedický YouTube

      1 / 5

      ✪ Objektově orientované programování v roce 2019

      ✪ Objektově orientovaný design, Část 1 – Jak jsou navrhovány třídy

      ✪ Základní principy objektově orientovaného programování. Co je OOP a proč je potřeba?

      ✪ Základy OOP v C++

      ✪ Objektově orientované programování. Třídy a objekty. Lekce 3

      titulky

    Základní pojmy

    Abstrakce dat Abstrakce znamená zvýraznění smysluplných informací a vyloučení irelevantních informací z úvahy. OOP bere v úvahu pouze abstrakci dat (často označovanou jednoduše jako „abstrakce“), která implikuje soubor smysluplných charakteristik objektu, který je dostupný zbytku programu. Encapsulation Encapsulation je systémová vlastnost, která umožňuje kombinovat data a metody, které s nimi pracují ve třídě. Některé jazyky (jako C++, Java nebo Ruby) přirovnávají zapouzdření ke skrytí, ale jiné (Smalltalk, Eiffel, OCaml) tyto pojmy rozlišují. Dědičnost Dědičnost je vlastnost systému, která vám umožňuje popsat novou třídu na základě existující třídy s částečně nebo zcela vypůjčenou funkčností. Třída, ze které dědíte, se nazývá základní, nadřazená nebo nadřazená třída. Nová třída je potomkem, následníkem, potomkem nebo odvozenou třídou. Polymorfismus podtypu Polymorfismus podtypu (v OOP jednoduše nazývaný "polymorfismus") je systémová vlastnost, která umožňuje používat objekty se stejným rozhraním bez informací o typu a vnitřní struktuře objektu. Jiný druh polymorfismu - parametrický - v OOP se nazývá zobecněné programování. Třída A je univerzální, komplexní datový typ, který se skládá z tematicky jednotného souboru „polí“ (proměnných více elementárních typů) a „metod“ (funkcí pro práci s těmito poli), jedná se tedy o model informační entity. s interním a externím rozhraním pro obsluhu jeho obsahu (polní hodnoty). Ve třídách se hojně využívají zejména speciální bloky jedné nebo častěji dvou párových metod, které mají na starosti elementární operace s určitým polem (rozhraní přiřazení hodnot a čtení), které napodobují přímý přístup do pole. Tyto bloky se nazývají „vlastnosti“ a mají téměř identický specifický název se svým polem (například název pole může začínat malými písmeny a název vlastnosti může začínat velké písmeno). Dalším projevem rozhraní třídy je, že při kopírování odpovídající proměnné prostřednictvím přiřazení se zkopíruje pouze rozhraní, ale ne samotná data, to znamená, že třída je referenčním datovým typem. Objektová proměnná daného typu třídy se nazývá instance této třídy. Současně v některých prováděcích systémech může být třída také reprezentována nějakým objektem během provádění programu prostřednictvím dynamické identifikace datového typu. Třídy jsou obvykle navrženy tak, aby byla zajištěna integrita dat objektu a také pohodlné a jednoduché rozhraní odpovídající povaze objektu a řešené úloze. Na druhé straně je integrita předmětné oblasti objektů a jejich rozhraní, stejně jako pohodlí jejich designu, zajištěna dědičností. Objekt Entita v adresovém prostoru výpočetního systému, která se objeví, když je vytvořena instance třídy (například po spuštění výsledků kompilace a propojení zdrojového kódu pro spuštění).

    Klasifikace podtypů OOP

    Luca Cardelli a Martin Abadi vytvořili teoretické zdůvodnění OOP a klasifikaci založenou na tomto zdůvodnění. Poznamenávají, že pojmy a kategorie, které identifikovali, se nenacházejí společně ve všech OO jazycích, většina jazyků podporuje pouze podmnožiny teorie a někdy i zvláštní odchylky od ní.

    Nejvýraznější rozdíly v projevu ukazatelů kvality mezi jazyky různých typů:

    • V běžných jazycích jsou deklarované principy zaměřeny na zvýšení inherentně nízké míry opětovného použití kódu pro imperativní programování. U polymorfně typizace znamená aplikace OOP konceptů naopak její zjevný pokles v důsledku přechodu od parametrického polymorfismu k polymorfismu ad hoc. V dynamicky typovaných jazycích (Smalltalk, Python, Ruby) se tyto principy používají k logické organizaci programu a jejich dopad na míru opětovného použití je obtížné předvídat – velmi záleží na disciplíně programátora. Například v CLOS jsou multimetody současně funkcemi první třídy, což nám umožňuje uvažovat je současně a jako související kvantifikovány a jako zobecněné (skutečně polymorfní).
    • Používání tradičních OO jazyků nominativní typizace, tedy přípustnost společného užívání objektů různých tříd pouze tehdy, je-li vztah mezi třídami výslovně uveden. Polymorfně typované jazyky se vyznačují strukturální typizace, to jest párování tříd mezi sebou stejným mechanismem jako párování čísla 5 s typem int . Dynamicky typované jazyky zde také zaujímají střední pozici.

    Zobecněné odůvodnění dynamické plánování(včetně množného čísla) postavil Giuseppe Castagna v polovině 90. let.

    Příběh

    OOP vzniklo jako výsledek rozvoje ideologie procedurálního programování, kde data a podprogramy (procedury, funkce) pro jejich zpracování spolu formálně nesouvisí. Pro další vývojčasto objektově orientované programování velká důležitost mají koncepty události (tzv. event-oriented programming) a komponenty (component programming, COP).

    Předměty interagují prostřednictvím . Výsledkem dalšího vývoje OOP bude zřejmě programování orientované na agenty, kde agenti- nezávislé části kódu na úrovni běhu. Agenti interagují změnou prostředí ve kterém se nacházejí.

    Jazykové konstrukty, které strukturálně přímo nesouvisejí s objekty, ale doprovázejí je pro jejich bezpečný (výjimečné situace, kontroly) a efektivní provoz, jsou z nich zapouzdřeny do aspektů (v aspektově orientovaném programování). Objektově orientované programování rozšiřuje koncept objektu tím, že poskytuje jednotnější a nezávislejší interakci objektů. Může to být přechodná fáze mezi OOP a programováním agentů z hlediska jejich nezávislé interakce.

    Prvním programovacím jazykem, který navrhl základní koncepty, které se později vyvinuly do paradigmatu, byla Simula, ale termín „objektově orientovaný“ se v souvislosti s používáním tohoto jazyka nepoužíval. V době jeho vzniku v roce 1967 v něm byly navrženy revoluční myšlenky: objekty, třídy, virtuální metody atd., ale to vše nebylo současníky vnímáno jako něco grandiózního. Ve skutečnosti byla Simula „Algol s třídami“, který usnadnil vyjádření mnoha složitých konceptů v procedurálním programování. Koncept třídy v Simule lze plně definovat prostřednictvím složení konstruktů Algol (tj. třída v Simule je něco komplexního, popsaného pomocí primitiv).

    „Nový úhel“ (jiný než procedurální) pohled na programování nabídli Alan Kay a Dan Ingalls v jazyce Smalltalk. Zde se koncept třídy stal základní myšlenkou pro všechny ostatní jazykové konstrukty (tj. třída ve Smalltalku je primitivum, jehož prostřednictvím jsou popsány složitější konstrukty). Byl to on, kdo se stal prvním rozšířeným objektově orientovaným programovacím jazykem.

    V současné době je počet aplikovaných programovacích jazyků (list languages), které implementují objektově orientované paradigma, největší ve srovnání s ostatními paradigmaty. Nejběžnější jazyky v oboru (C++, Delphi, C#, Java atd.) implementují objektový model Simula. Příklady jazyků založených na modelu Smoltok jsou Objective-C, Python, Ruby.

    Definice OOP a jeho hlavní pojmy

    V centru OOP je koncept objekt. Objekt je entita, které lze posílat zprávy a která na ně může odpovídat pomocí svých dat. Objekt je instancí třídy. Data objektu jsou před zbytkem programu skryta. Skrytí dat se nazývá zapouzdření.

    Přítomnost zapouzdření je dostatečná pro objektivitu programovacího jazyka, ale ještě neznamená jeho objektovou orientaci – to vyžaduje přítomnost dědičnosti.

    Ale ani přítomnost zapouzdření a dědičnosti nečiní programovací jazyk plně objektově orientovaným z pohledu OOP. Hlavní výhody OOP se projeví až tehdy, když programovací jazyk implementuje podtypový polymorfismus – schopnost zacházet s objekty s různými implementacemi jednotným způsobem za předpokladu, že existuje společné rozhraní.

    Potíže s definicí

    OOP má více než čtyřicetiletou historii, ale navzdory tomu stále neexistuje jasná, obecně přijímaná definice této technologie. Základní principy stanovené v prvních objektových jazycích a systémech prošly významnou změnou (nebo zkreslením) a doplněním s četnými následnými implementacemi. Zhruba od poloviny 80. let se navíc termín „objektově orientovaný“ stal módním, v důsledku toho se mu stalo totéž, co o něco dříve s pojmem „strukturální“ (který se stal módou po rozšíření strukturálních programovací technologie) – uměle se „připojoval“ k jakémukoli novému vývoji, aby byl atraktivní. Björn Stroustrup v roce 1988 napsal, že ospravedlnění „objektové orientace“ něčeho ve většině případů vede k falešnému sylogismu: „X je dobré. Orientace objektu je dobrá. Proto, X je objektově orientovaný."

    Roger King tvrdil, že jeho kočka byla objektově orientovaná. Kočka kromě svých dalších předností projevuje charakteristické chování, reaguje na zprávy, je obdařena zděděnými reakcemi a ovládá svůj vlastní, zcela nezávislý, vnitřní stav.

    Obecnost mechanismu zasílání zpráv má však i druhou stránku – „plnohodnotné“ předávání zpráv vyžaduje další režii, což není vždy přijatelné. Proto tento koncept používá mnoho moderních objektově orientovaných programovacích jazyků "odeslání zprávy jako volání metody"- objekty mají zvenčí přístupné metody, jejichž voláním je zajištěna interakce objektů. Tento přístup byl implementován v obrovském množství programovacích jazyků, včetně C++ , Object Pascal , Java , Oberon-2 . To však vede k tomu, že zprávy již nejsou nezávislými objekty a v důsledku toho nemají atributy, což zužuje možnosti programování. Některé jazyky používají hybridní reprezentaci demonstrující výhody obou přístupů současně – například CLOS , Python .

    Pojem virtuální metody, podporovaný těmito a dalšími moderními jazyky, se objevil jako prostředek k zajištění provádění požadovaných metod při použití polymorfních proměnných, tedy v podstatě jako pokus rozšířit schopnost volání metod implementovat část funkcí poskytovaných mechanismus zpracování zpráv.

    Funkce implementace

    Jak již bylo zmíněno výše, v moderních objektově orientovaných programovacích jazycích je každý objekt hodnotou, která patří do určité třídy. Třída je složený datový typ deklarovaný programátorem, který obsahuje:

    Datová pole Parametry objektu (samozřejmě ne všechny, ale pouze nezbytné v programu), které definují jeho stav (vlastnosti objektu předmětové oblasti). Někdy se datová pole objektu označují jako vlastnosti objektu, což může být matoucí. Fyzicky jsou pole hodnoty (proměnné, konstanty) deklarované jako patřící do třídy. Metody Procedury a funkce spojené s třídou. Definují akce, které lze provádět s objektem tohoto typu a které může provádět samotný objekt.

    Třídy mohou po sobě dědit. Podřízená třída obdrží všechna pole a metody nadřazené třídy, ale může je doplnit svými vlastními nebo přepsat stávající. Většina programovacích jazyků podporuje pouze jedinou dědičnost (třída může mít pouze jednu nadřazenou třídu), jen některé umožňují vícenásobnou dědičnost – generování třídy ze dvou nebo více nadřazených tříd. Vícenásobná dědičnost vytváří řadu problémů, jak logických, tak čistě implementačních, takže její plná podpora není rozšířená. Místo toho se v 90. letech objevil koncept rozhraní a začal být aktivně zaváděn do objektově orientovaných jazyků. Rozhraní je třída bez polí a bez implementace, včetně pouze záhlaví metod. Pokud třída zdědí (nebo se říká, že implementuje) rozhraní, musí implementovat všechny své členské metody. Použití rozhraní poskytuje relativně levnou alternativu k vícenásobné dědičnosti.

    Interakce objektů je v naprosté většině případů zajištěna vzájemným voláním metod.

    Zapouzdření je zajištěno následujícími prostředky:

    Řízení přístupu Protože metody tříd mohou být jak čistě interní, poskytující logiku fungování objektu, tak externí, s jejichž pomocí objekty interagují, je nutné zajistit, aby první byly skryté, zatímco druhé přístupné zvenčí. K tomu jsou do jazyků zavedeny speciální syntaktické konstrukce, které explicitně nastavují rozsah každého člena třídy. Tradičně se jedná o veřejné, chráněné a soukromé modifikátory, které označují veřejné členy třídy, členy třídy přístupné uvnitř třídy a z podřízených tříd a skryté, přístupné pouze uvnitř třídy. Specifické názvosloví modifikátorů a jejich přesné významy se liší různé jazyky. Přístupové metody Pole třídy by obecně neměla být přístupná zvenčí, protože takový přístup by umožnil libovolnou změnu vnitřního stavu objektů. Pole jsou proto obvykle prohlášena za skrytá (nebo jazyk v zásadě neumožňuje přístup k polím třídy zvenčí) a pro přístup k datům v polích se používají speciální metody zvané accessors. Takové metody buď vracejí hodnotu určitého pole, nebo do tohoto pole zapisují novou hodnotu. Při zápisu může přístupový objekt zkontrolovat, zda je zapisovaná hodnota platná, a v případě potřeby provést další manipulace s daty objektu tak, aby zůstala správná (vnitřně konzistentní). Přístupové metody se také nazývají accessors (z anglického access - access), a jednotlivě - getters (anglicky get - čtení) a settery (anglicky set - psaní). Vlastnosti objektu Pseudo-field, dostupné pro čtení a/nebo zápis. Vlastnosti vypadají jako pole a používají se stejným způsobem jako přístupná pole (až na některé výjimky), ale ve skutečnosti se při přístupu k nim volají metody přístupového objektu. Vlastnosti lze tedy považovat za „chytrá“ datová pole, která doprovázejí přístup k vnitřním datům objektu některými akcemi navíc (např. když je změna souřadnice objektu doprovázena jeho překreslením na nové místo). Vlastnosti nejsou ve skutečnosti nic jiného než syntaktický cukr, protože nepřidávají žádné nové funkce, ale pouze skrývají volání metod přístupového objektu. Specifická jazyková implementace vlastností se může lišit. Například deklarace vlastnosti přímo obsahuje kód pro metody přístupového objektu, které jsou volány pouze při práci s vlastnostmi, to znamená, že nevyžaduje samostatné metody přístupového objektu, které jsou k dispozici pro okamžité volání. V Delphi obsahuje deklarace vlastnosti pouze názvy metod přístupového objektu, které by měly být volány při přístupu k poli. Samotné přístupové objekty jsou běžné metody s některými dalšími požadavky na podpis.

    Polymorfismus je implementován zavedením pravidel do jazyka, podle kterých lze proměnné typu „class“ přiřadit objekt libovolné třídy potomka její třídy.

    Návrh programu obecně

    OOP je zaměřena na vývoj velkých softwarových systémů vyvíjených týmem programátorů (možná poměrně rozsáhlým). Návrh systému jako celku, tvorbu jednotlivých komponent a jejich integraci do finálního produktu často provádějí různí lidé a není jediný specialista, který by o projektu věděl vše.

    Objektově orientovaný design se zaměřuje na popis struktury navrhovaného systému (priorita před popisem jeho chování, na rozdíl od funkcionálního programování), tedy ve skutečnosti jako odpověď na dvě hlavní otázky:

    • Z jakých částí se systém skládá?;
    • Jaká je odpovědnost každé jeho části.

    Přidělování dílů probíhá tak, aby každý měl minimální a přesně definovaný soubor vykonávaných funkcí (povinností) a zároveň co nejméně interagoval s ostatními díly.

    Další zpřesňování vede k výběru menších fragmentů popisu. Jak je popis podrobný a je určena odpovědnost, odhalují se data, která je třeba uložit, přítomnost podobných agentů v chování, kteří se stávají kandidáty na implementaci ve formě tříd se společnými předky. Po výběru komponent a definování rozhraní mezi nimi lze implementaci každé komponenty provádět téměř nezávisle na ostatních (samozřejmě za dodržení příslušné technologické disciplíny).

    Velký význam má správná konstrukce třídní hierarchie. Jedním ze známých problémů velkých systémů budovaných pomocí technologie OOP je tzv problém křehkosti základní třídy. Spočívá v tom, že v pozdějších fázích vývoje, kdy byla vytvořena hierarchie tříd a na jejím základě bylo vyvinuto velké množství kódu, se ukazuje být obtížné nebo dokonce nemožné provádět jakékoli změny v kódu základní třídy hierarchie (ze kterých jsou generovány všechny nebo mnoho tříd působících v systému). I když změny, které provedete, neovlivní rozhraní základní třídy, změna jejího chování může ovlivnit podřízené třídy nepředvídatelným způsobem. Když hlavní systém vývojář základní třídy prostě není schopen předvídat důsledky změn, neví ani, jak se základní třída používá a na jakých vlastnostech jejího chování závisí správné fungování potomkových tříd.

    Různé OOP metodiky

    Programování komponent je další fází vývoje OOP; prototypové a třídně orientované programování jsou různé přístupy k vytváření programu, které lze kombinovat a mají své výhody a nevýhody.

    Komponentní programování

    Komponentově orientované programování je jakousi „nadstavbou“ nad OOP, souborem pravidel a omezení zaměřených na budování velkých vývojových softwarových systémů s velký časživot. Softwarový systém v této metodice je sada komponent s dobře definovanými rozhraními. Změny v stávající systém jsou zaváděny vytvořením nových součástí navíc nebo jako náhrada za dříve existující. Při vytváření nových komponent založených na dříve vytvořených je zakázáno použití dědičnosti implementace - nová součástka může zdědit pouze rozhraní ze základny. Tímto způsobem programování komponent obchází problém křehkosti základní třídy.

    Prototypové programování

    Prototypové programování, i když si zachovalo některé rysy OOP, opustilo základní koncepty třídy a dědičnosti.

    • Prototyp je objekt-vzorek, v jehož obrazu a podobě jsou vytvořeny další objekty. Kopírované objekty si mohou zachovat svůj vztah k nadřazenému objektu automatickým zděděním změn prototypu; tato funkce je definována v konkrétním jazyce.
    • Místo mechanismu pro popis tříd a generování instancí poskytuje jazyk mechanismus pro vytváření objektu (zadáním sady polí a metod, které objekt musí mít) a mechanismus pro klonování objektů.
    • Každý nově vytvořený objekt je „instancí bez třídy“. Každý objekt může být prototyp- použít k vytvoření nového objektu pomocí operace klonování. Po klonování lze nový objekt změnit, zejména přidat nová pole a metody.
    • Klonovaný objekt se buď stane úplnou kopií prototypu, uloží všechny hodnoty jeho polí a zduplikuje své metody, nebo si zachová odkaz na prototyp bez zahrnutí klonovaných polí a metod, dokud se nezmění. V druhém případě poskytuje runtime mechanismus delegace- pokud při přístupu k objektu neobsahuje požadovanou metodu nebo datové pole, je volání předáno prototypu, od něj v případě potřeby dále v řetězci.

    Třídně orientované programování

    Třídně orientované programování je programování zaměřené na data, kde jsou data a chování neoddělitelně propojeny. Data a chování dohromady tvoří třídu. V souladu s tím jsou v jazycích založených na konceptu „třídy“ všechny objekty rozděleny do dvou hlavních typů - třídy a instance. Třída definuje strukturu a funkcionalitu (chování), která je stejná pro všechny instance této třídy. Instance je datový nosič – to znamená, že má stav, který se mění v souladu s chováním specifikovaným třídou. V třídně orientovaných jazycích se nová instance vytvoří voláním konstruktoru třídy (třeba se sadou parametrů). Výsledná instance má strukturu a chování pevně zakódované svou třídou.

    Výkon objektových programů

    Gradi Buch poukazuje na následující důvody, které vedou ke snížení výkonu programu v důsledku použití objektově orientovaných nástrojů:

    Dynamické vázání metod Zajištění polymorfního chování objektů vede k nutnosti vázat metody volané programem (tedy určit, která konkrétní metoda bude volána) nikoli ve fázi kompilace, ale během provádění programu, což zabere další čas. Dynamická vazba je přitom ve skutečnosti vyžadována ne pro více než 20 % hovorů, ale některé OOP jazyky ji používají neustále. Značná hloubka abstrakce OOP vývoj často vede k vytváření „vrstvených“ aplikací, kde se provedení požadované akce objektem redukuje na mnoho volání objektů nižší úrovně. V takové aplikaci je spousta volání metod a návratů metod, což samozřejmě ovlivňuje výkon. Dědičnost kód „rozmazává“ Kód související s „konečnými“ třídami hierarchie dědičnosti, které program obvykle přímo používá, není pouze v těchto třídách samotných, ale také v třídách jejich předků. Metody patřící do stejné třídy jsou ve skutečnosti popsány v různých třídách. To vede ke dvěma nepříjemným věcem:

    • Rychlost překladu je snížena, protože linker musí načíst popisy všech tříd hierarchie.
    • Výkon programu v systému s pamětí stránek klesá - protože metody jedné třídy jsou fyzicky umístěny v různá místa kód, daleko od sebe, při spouštění programových fragmentů, které aktivně přistupují ke zděděným metodám, je systém nucen provádět časté přepínání stránek.
    Zapouzdření snižuje rychlost přístupu k datům Zákaz přímého přístupu k polím tříd zvenčí vede k nutnosti vytvářet a používat přístupové metody. A psaní, kompilace a provádění přístupových metod je spojeno s dodatečnými náklady. Dynamické vytváření a ničení objektů Dynamicky vytvářené objekty jsou obvykle alokovány na hromadě, což je méně efektivní než jejich umístění na zásobník a navíc pro ně staticky alokovat paměť v době kompilace.

    Navzdory těmto nedostatkům Booch tvrdí, že výhody používání OOP jsou větší. Kromě toho, zvýšení výkonu díky lepší organizaci kódu OOP, říká, v některých případech kompenzuje další režii na běh programu. Můžete si také všimnout, že mnoho efektů snížení výkonu lze vyhladit nebo dokonce úplně odstranit díky vysoce kvalitní optimalizaci kódu kompilátorem. Například výše uvedené snížení rychlosti přístupu k polím tříd kvůli použití přístupových objektů je eliminováno, pokud kompilátor místo volání přístupového objektu používá inline substituci (moderní kompilátory to dělají zcela sebevědomě).

    Kritika OOP

    Navzdory některým výtkám vůči OOP se toto paradigma v současné době používá v naprosté většině průmyslových projektů. Nelze však předpokládat, že OOP je nejlepší programovací technika ve všech případech.

    Kritika OOP:

    • Nebyl prokázán žádný významný rozdíl v produktivitě vývoje software mezi OOP a procedurálním přístupem.
    • Christopher Date poukazuje na to, že je nemožné srovnávat OOP s jinými technologiemi, a to především kvůli nedostatku přísné a obecně přijímané definice OOP.
    • Alexander Stepanov v jednom ze svých rozhovorů poukázal na to, že OOP je „metodologicky špatný“ a že „... OOP je prakticky stejný podvod jako umělá inteligence ...“.
    • Frederick Brooks poukazuje na to, že nejobtížnější částí vývoje softwaru je „…specifikace, návrh a testování konceptuálních konstruktů, nikoli práce na vyjádření těchto konceptuálních konstruktů…“. OOP (spolu s takovými technologiemi, jako je umělá inteligence, verifikace programů, automatické programování, grafické programování, expertní systémy atd.) podle něj není „stříbrnou kulkou“, která by mohla snížit složitost vývoje softwarových systémů řádově velikost. Podle Brookse „...OOP pouze snižuje složitost vnesenou do designového výrazu. Design zůstává ze své podstaty složitý…“ .
    • Edsger Dijkstra zdůraznil: „...to, co společnost ve většině případů požaduje, je elixír na všechny nemoci. Samozřejmě, že „elixír“ má velmi působivá jména, jinak bude velmi obtížné něco prodat: „Strukturální analýza a návrh“, „Softwarové inženýrství“, „Modely zralosti“, „Manažerské informační systémy“, „Integrovaná prostředí“ podpora projektu ““, „Objektová orientace“, „Reengineering Obchodní procesy“…“ .
    • Niklaus Wirth se domnívá, že OOP není nic jiného než triviální nadstavba nad strukturovaným programováním a přehánění jeho důležitosti, vyjádřené mimo jiné zařazováním stále nových módních „objektově orientovaných“ nástrojů do programovacích jazyků, škodí kvalitu vyvíjeného softwaru.
    • Patrick Killelia ve své knize Tuning the Web Server napsal: „... OOP vám nabízí mnoho způsobů, jak zpomalit vaše programy...“.
    • Známý přehledový článek o problémech moderního programování OOP některé uvádí typické problémy OOP [ ] .
    • V programátorském folklóru se rozšířila kritika objektově orientovaného přístupu ve srovnání s funkčním přístupem využívajícím metaforu „ Podstatné jméno Království z eseje Steva Yeggiho.

    Pokud se pokusíme klasifikovat kritiku OOP, můžeme zdůraznit několik aspektů kritiky tohoto přístupu k programování.

    Kritika OOP reklamy Kritika je vyjádřena nebo implikována v práci některých OOP propagandistů, stejně jako v propagačních materiálech pro "objektově orientované" vývojové nástroje, pojem objektové programování jako jakýsi druh všemocného přístupu, který magicky eliminuje složitost programování . Jak mnozí poznamenali, včetně výše zmíněných Brooks a Dijkstra, „neexistuje žádná stříbrná kulka“ – bez ohledu na to, jakého programovacího paradigmatu se vývojář drží, vytváří netriviální komplex. softwarový systém vždy spojeno se značnými náklady na intelektuální zdroje a čas. Z nejkvalifikovanějších odborníků v oblasti OOP zpravidla nikdo nepopírá platnost tohoto typu kritiky. Zpochybňování efektivity vývoje OOP Kritici zpochybňují tezi, že vývoj objektově orientovaných programů vyžaduje méně zdrojů nebo vede k lepšímu softwaru. Porovnání nákladů na vývoj různé metody, na základě čehož dochází k závěru, že OOP nemá v tomto směru žádné výhody. Vzhledem k extrémní složitosti objektivního srovnávání různého vývoje jsou taková srovnání přinejmenším diskutabilní. Na druhou stranu se ukazuje, že stejně kontroverzní jsou i prohlášení o účinnosti OOP. Výkon objektově orientovaných programů Poukazuje se na to, že řada „vlastních vlastností“ technologie OOP činí programy postavené na jejím základě technicky méně efektivní ve srovnání s podobnými neobjektovými programy. I když nepopíráme, že skutečně existují další režie pro spouštění programů OOP (viz část "Výkon" výše), je třeba poznamenat, že dopad snížení výkonu kritici často zveličují. V moderní podmínky Když jsou technické možnosti počítačů extrémně velké a neustále rostou, pro většinu aplikačních programů je technická efektivita méně významná než funkčnost, rychlost vývoje a udržovatelnost. Pouze u velmi omezené třídy programů (software vestavěných systémů, ovladače zařízení, software nízké úrovně, vědecký software) zůstává výkon kritickým faktorem. Kritika jednotlivých technologických řešení v jazycích a knihovnách OOP Tato kritika je četná, ale netýká se OOP jako takového, ale přijatelnosti a použitelnosti v konkrétní případy určité implementace jejích mechanismů. Jedním z oblíbených předmětů kritiky je jazyk C++, který je jedním z nejběžnějších průmyslových jazyků OOP.

    Objektově orientované jazyky

    Mnoho moderní jazyky speciálně navržený pro usnadnění objektově orientovaného programování. Je však třeba poznamenat, že techniky OOP lze aplikovat na neobjektově orientovaný jazyk a naopak, použití objektově orientovaného jazyka vůbec neznamená, že se kód automaticky stane objektově orientovaným.

    Objektově orientovaný jazyk (OOL) obvykle obsahuje následující sadu prvků:

    • Deklarování tříd s poli (data - členové třídy) a metodami (funkce - členové třídy).
    • Mechanismus rozšíření třídy (dědění) - generování nové třídy z existující s automatické zapínání všechny vlastnosti implementace třídy předka do třídy potomka. Většina seznamů CRL podporuje pouze jednu dědičnost.
    • Polymorfní proměnné a parametry funkcí (metod), které umožňují přiřadit instance různých tříd stejné proměnné.
    • Polymorfní chování instancí tříd pomocí virtuálních metod. V některých seznamech CRL jsou všechny metody třídy virtuální.

    Některé jazyky přidávají k zadané minimální sadě jisté dodatečné finanční prostředky. Mezi nimi:

    • Konstruktory, destruktory, finalizátory;
    • Vlastnosti (příslušenství);
    • indexátory;
    • Prostředky pro řízení viditelnosti komponent třídy (rozhraní nebo modifikátory přístupu, jako veřejné, soukromé, chráněné, funkce atd.).

    Některé jazyky plně dodržují principy OOP - v nich jsou všechny hlavní prvky objekty, které mají stav a související metody. Příklady podobných jazyků jsou Smalltalk, Eiffel. Existují hybridní jazyky, které kombinují objektový subsystém jako celek se subsystémy jiných paradigmat jako „dva nebo více jazyků v jednom“, což vám umožňuje kombinovat v jednom programu. objektové modely s ostatními a stírání hranice mezi objektově orientovaným a jiným paradigmatem kvůli nestandardním funkcím balancujícím mezi OOP a jinými paradigmaty (jako je vícenásobné odesílání, parametrické třídy, možnost manipulovat s metodami tříd jako s nezávislými objekty atd.). Příklady takových jazyků:

    před 1 rokem | 13,4 tis

    Každý uchazeč, který se chce dostat na místo programátora ve velké firmě, si musí odpovědět na otázku, co je to za typ programování. Pokud má programátor potíže s odpovědí, ve většině případů tazatel zdvořile oznámí, že rozhovor skončil. Pro programátory je těžké získat normální práci bez zaměření na tento segment.

    Abyste na tuto otázku mohli adekvátně odpovědět, budete se muset seznámit nejen se základními vlastnostmi OOP, ale také porozumět některým pojmům – například polymorfismus, stejně jako zapouzdření a dědičnost. Od v modulu se můžete seznámit s teoretickým základem OOP a poznatky aplikovat v praxi v modulu MVC - celý modul.

    Úvod do OOP

    OOP je velmi oblíbené programovací paradigma, které nahradilo zastaralý procedurální přístup v programování. Stojí za to podrobněji zvážit vlastnosti procedurálního programování, abychom pochopili, jak se procedurální programování liší od OOP.

    Takže program napsaný pomocí procedurálního přístupu k programování je monolitický program, který obsahuje určitý počet instrukcí potřebných programátorem, stejně jako podprogramy.

    Abyste okamžitě pochopili rozdíly mezi těmito programovacími metodami, musíte kód zvážit několika způsoby:

    Procedurální programování:

    $value = "Ahoj!"; echo $value; !}

    OOP:

    třída Člověk ( soukromé $slova; veřejná funkce setWords($slova) ( $toto->slova = $slova; ) veřejná funkce getWords() ( vrátit $toto->slova; ) veřejná funkce sayIt() ( vrátit $toto-> getWords(); ) ) $human = new Human(); $human->setWords("Ahoj!"); echo $human->sayIt();

    Stojí za to okamžitě zdůraznit viditelný rozdíl - v první verzi je vše mnohem jednodušší, méně kódu. Mnoha lidem se bude zdát OOP kód příliš složitý a zvolí první možnost, ale to je pouze prvotní zavádějící dojem.

    V tento případ, při výběru přístupu je třeba vzít v úvahu vlastnosti přijatého úkolu. Procedurální přístup je ideální pro tvorbu jednoduchého kódu pro krátkodobé použití – tento přístup zvolte, pokud kód nebude mít více než 5 řádků.

    Pro pravidelně se opakující úkol, který je složitější, je nejlepší zvolit OOP.

    Co je TŘÍDA

    Všechno je zde docela jednoduché - jsou to metody i pole programu. Jako příklad si vezměte člověka:

    Třída Člověk ( soukromé $words; veřejná funkce setWords($words) ( $this->words = $words; ) veřejná funkce getWords() ( return $this->words; ) veřejná funkce sayIt() ( return $this-> getWords(); ))

    Všechno je zde docela jednoduché, Human je název třídy, $words je proměnná (pole) a setWords, getWords(), sayIt() jsou metody.

    Některé základní OOP principy

    Základem OOP jsou 3 hlavní principy najednou. Každý z těchto principů bude probrán podrobněji, abyste měli možnost porozumět všem funkcím OOP.

    Zapouzdření

    Ukážeme několik příkladů, které vám pomohou pochopit každý z prezentovaných principů. Zapouzdření je druh ochrany informací před externími uživateli.

    Aby bylo hned jasné, o co jde, uveďme si reálný příklad.

    Chcete uskutečnit určitý hovor pomocí svého telefonu – to nevyžaduje, abyste měli další znalosti v segmentu mobilních sítí, umístění věží a tak dále. Stačí vám jednodušší znalost - číslo vybraného účastníka a prostředky, které vám umožní uskutečnit plánovaný hovor.

    Zapouzdření poskytuje externím uživatelům (programátorům) přístup k metodám, které potřebují pro práci s vaším programem, zatímco všechny důležité interní metody zůstávají nepřístupné, prostě je externí uživatelé nepotřebují.

    Zde je příklad zapouzdření:

    Třída Člověk ( soukromá $slova; soukromá $sex; veřejná funkce setSex($sex) ( if($sex == "muž") ( $this->sex = "muž"; ) else if($sex == "žena" ") ( $this->sex = $sex; ) else ( echo "Chyba. Nastavit pouze mužské nebo ženské pohlaví"; ) ) veřejná funkce setWords($words) ( $this->words = $words; ) veřejná funkce getWords () ( return $this->words; ) public function sayIt() ( return $this->getWords(); ) ) $human = new Human(); $human->setSex("muž"); $human->setWords("Ahoj!"); echo $human->sayIt();

    Zde je zobrazen Člověk, do této třídy jsme přidali „pohlaví“ (pohlaví), které jsme označili jako soukromé – to neumožní externím uživatelům přístup.

    Zde je návod, jak by vypadal pokus o přístup k tomuto poli mimo samotnou třídu:

    $člověk->pohlaví = "11"; fatální chyba: Nemohu získat přístup k soukromému vlastnictví Člověk::$sex

    Zapouzdření je velmi užitečná vlastnost OOP a používá se poměrně často. Zapouzdření je neuvěřitelně užitečné, pokud se na tvorbě konkrétního projektu podílí celá skupina specialistů. Každý programátor bude pracovat s určitou třídou a metodami, přičemž nebude zasahovat do práce jiných specialistů.

    Dědictví

    Velmi důležitou vlastností OOP je také schopnost zdědit funkčnost konkrétní třídy do třídy jiné.

    A opět příklad ze života, který vám pomůže pochopit rysy dědičnosti.

    Každý člověk má při narození určitý soubor funkcí, jedná se o tzv. základní soubor – dýchání, trávení potravy, pláč.

    Jste spojením obrovského množství řetězců genů – od úplně prvních předků až po pokrevní rodiče. Pokud vezmeme v úvahu OOP, pak se v tomto případě dědická vlastnost neliší od prostého života.

    Jak to funguje? Existují nadřazené třídy se základní funkcionalitou – při vytváření nové třídy nebude nutné vytvářet nové základní dovednosti, ta zpočátku zdědí „základ“ nadřazené třídy. To značně zjednodušuje práci programátorů. Existuje slovo „extends“, které znamená dědičnost, nyní vám ukážeme konkrétní příklad:

    /* Nadřazená třída Human */ class Human ( private $name; /* Konstruktor (ve kterém nastavujeme pole $name při vytváření instance třídy) */ public function __construct($name) ( $this->name = $name; ) /* Metoda say() Za předpokladu, že člověk může zpočátku mluvit */ public function say() ( echo "Moje jméno je ".$this->name." a "; ) ) /* Class Man. S klíčovým slovem extends zdědíme nadřazený člověk */ class Man extends Human ( public function beard() ( echo "rostou mi vousy"; ) ) /* Class Woman. Zdědíme rodiče Human s klíčovým slovem extends */ class Women extends Human ( public function bearChildren() ( echo "Mám děti"; ) ) /* Vytvořte instanci třídy Man a zavolejte metody. */ $man = new Man("Sergey"); $man->say(); $man->vous(); /* Vytvořte instanci třídy Women a zavolejte metody. */ $women = new Women("Maria"); $zeny->say(); $zeny->bearDeti();

    Co uvidíme jako výsledek:

    Jmenuji se Sergey a rostou mi vousy Jmenuji se Maria a mám děti

    Pokud vezmeme v úvahu vytvořené třídy - obě mají základní soubor dovedností, ale existují rozdíly - "Muž" si nechá narůst vousy, "Žena" porodí dítě.

    Metoda nazvaná __construct je konstruktorem třídy.

    Polymorfismus

    Stejná metoda programu může vykazovat různé chování. To je docela těžké hned pochopit, takže tradičně používáme jednodušší příklad, abyste pochopili rysy polymorfismu:

    Představte si, že jste přišli do obchodu s potravinami – pokladní vám může prodat jakékoli produkty, přijmout platbu kartou nebo v hotovosti.

    No, jak? Je nyní snazší pochopit odlišné chování jedné metody v OOP?

    Příklad polymorfismu:

    /* Toto je rozhraní Say */ rozhraní Say ( public function say(); ) /* Toto je abstraktní třída Human implementující rozhraní Say */ abstract class Human implementuje Say( private $name; public function __construct($name) ( $this-> name = $name; ) public function getName() ( return $this->name; ) ) /* Třída Man zdědí třídu Human a musí implementovat metodu say() */ class Man extends Human ( public function __construct($name) ( parent::__construct($name); ) public function beard() ( echo "Rostou mi vousy"; ) public function say() ( echo "Mám mužský hlas, jmenuji se ".$this->getName()." a "; ) ) /* Třída Women zdědí třídu Human a musí implementovat metodu say() */ class Women extends Human ( public function __construct($name) ( parent::__construct($name); ) public function bearChildren () ( echo „Mám děti“; ) veřejná funkce say() ( echo „Mám ženský hlas, jmenuji se ".$this->getName()." a "; ) ) $muž = nový muž("Sergey"); $muž->say(); $muž->vous(); $ženy = nové ženy("Maria"); $ženy->say() $women->bearChildren(); ?>

    Výsledek:

    Mám mužský hlas, jmenuji se Sergey a rostou mi vousy, mám ženský hlas, jmenuji se Maria a mám děti

    Naše třídy byly upraveny, objevily se nové koncepty - Rozhraní i Abstraktní programování. Tento aspekt zvážíme o něco později.

    Všimněte si rozdílné implementace metody say() ve třídách Muž a také Ženy - To se nazývá polymorfismus.

    Vlastnosti rozhraní

    Rozhraní je třída šablony, neexistuje žádná implementace. Rozhraní umožňuje definovat určité metody, které vyžadují následnou implementaci.

    Zvažte předchozí příklad:

    /* Toto je rozhraní Say */ rozhraní Say ( public function say(); )

    Toto rozhraní musí být implementováno v abstraktní třídě Human. To je docela jednoduché - najdeme název třídy a hned za něj přidáme "nástroje".

    Abstraktní třída

    Abstraktní třída v OOP je třída šablony, kterou nelze vytvořit.

    Příklad toho, co neumíme:

    $člověk = nový Člověk("jméno");

    V každém případě obdržíme chybu.

    Existuje možnost dědičnosti třídy Abstract. Další příklad abstraktní třídy:

    /* Toto je abstraktní třída Human, která implementuje rozhraní Say */ abstract class Human implementuje Say( private $name; public function __construct($name) ( $this->name = $name; ) public function getName() ( return $this-> jméno; ) )

    závěry

    OOP je neuvěřitelně pohodlný moderní způsob, který vám umožňuje kompetentně organizovat struktury poměrně složitých programů. Ostatní vývojáři budou moci podporovat rostoucí funkční projekt díky OOP. To je poměrně důležitá výhoda OOP.

    Ve velkém kurzu v modulech se seznámíte s teoretickými základy OOP, a praktickou implementací - v modulu.

    Uvedli jsme poměrně jednoduché příklady – to je skvělá příležitost pro každého začátečníka v segmentu programování! Doufáme, že jsme vám pomohli porozumět funkcím OOP, naučit se nejdůležitější principy, abyste mohli dále zlepšovat své dovednosti. Několik budoucích článků se zaměří na to, co je důležité klíčová slova veřejné, soukromé, chráněné, statické. Podívejte se na všechny funkce na velmi jednoduchých příkladech.

    Koncept objektově orientovaného programování (OOP) se objevil před více než čtyřiceti lety jako vývoj myšlenek procedurálního programování. Ideologie procedurálního programování není nic zvláštního: všechny programy jsou reprezentovány sadou procedur a funkcí, zatímco procedury a funkce samotné jsou sekvencemi příkazů, jejichž provedením počítač upravuje hodnoty proměnných v paměti. Hlavním programem v procedurálním programování je také procedura (funkce), v jejímž těle mohou být volání dalších procedur a funkcí - podprogramů. Podstata procedurálního programování je jednoduchá: data jsou oddělená, chování je oddělené. Z čeho se skládá procedurální programovací jazyk (jaké konstrukce obsahuje), jsem se pokusil shromáždit v samostatné části. Rozdělení kódu do podprogramů vám za prvé umožňuje zvýraznit opakovaně použitelné fragmenty kódu a za druhé dělá programový kód strukturovaným.

    Ideologie objektově orientovaného programování, jak název napovídá, je postavena na konceptu objektu. Objekt kombinuje data i chování. Objekt je jakákoli entita, se kterou se program zabývá, jmenovitě: objekty předmětové oblasti modelované programem; prostředky operačního systému; síťových protokolů a mnohem víc. Ve skutečnosti je objekt stejnou strukturou (složený typ), ale doplněnou o procedury a funkce, které řídí prvky této struktury. Například pro práci se souborem v procedurálním programovacím jazyce by se proměnná vytvořila samostatně pro uložení názvu souboru a zvlášť pro uložení jeho deskriptoru (jedinečného identifikátoru zdroje v operačním systému), stejně jako řada procedur pro práce se souborem: otevřete soubor, načtěte data ze souboru a zavřete soubor. Všechny tyto procedury by kromě obvyklých parametrů a proměnných pro uložení výsledku musely akceptovat stejný deskriptor, abychom pochopili, o kterém konkrétním souboru je řeč. V objektově orientovaném jazyce by byl za stejným účelem popsán objekt souboru, který by v sobě také ukládal jméno a deskriptor a poskytoval by uživateli procedury pro otevírání, čtení a zavírání sebe sama (soubor spojený s konkrétním objekt). Rozdíl by byl v tom, že handle by byl skryt před zbytkem programu, vytvořen v kódu procedury otevírání souboru a implicitně používán pouze samotným objektem. Uživatel objektu (programový kód programu mimo objekt) by tedy nemusel pokaždé předávat deskriptor v parametrech procedury. Objekt je soubor dat a metod pro práci s těmito daty, z nichž některá mohou být skryta okolnímu světu, ke kterému patří detaily implementace. Více o terminologii objektově orientovaného programování bude diskutováno později.

    Téměř vše je v objektově orientovaném programovacím jazyce objekt, kromě operátorů: oba elementární typy jsou objekty a popis chyby je objekt a konečně i hlavní program je objekt. Zbývá pochopit, co je objekt z pohledu samotného programu, jak je vytvořen a používán. Druhým základním konceptem OOP je třída. Třída je zcela nový datový typ ve srovnání s procedurálním programováním, jehož instance se nazývají objekty. Třída, jak již bylo zmíněno, je podobná složenému datovému typu nebo struktuře, ale doplněná o procedury a funkce (metody) pro práci s jejími daty. Nyní je čas popsat základní pojmy objektově orientovaného programování.

    Terminologie objektově orientovaného programování

    Než přistoupíme k popisu výhod, které OOP poskytuje softwarovým vývojářům v procesu navrhování, kódování a testování softwarových produktů, je nutné se seznámit s nejpoužívanějšími pojmy v této oblasti.

    • Třída– datový typ popisující strukturu a chování objektů.
    • Objekt je instancí třídy.
    • Pole– datový prvek třídy: proměnná elementárního typu, struktura nebo jiná třída, která je součástí třídy.
    • Stav objektu– sada aktuálních hodnot polí objektů.
    • Metoda Procedura nebo funkce, která se provádí v kontextu objektu, pro který je volána. Metody mohou změnit stav aktuálního objektu nebo stav objektů, které jim byly předány jako parametry.
    • Vlastnictví– speciální typ metod určených k úpravě jednotlivých polí objektu. Názvy vlastností jsou obvykle stejné jako názvy odpovídajících polí. Navenek vypadá práce s vlastnostmi úplně stejně jako práce s poli struktury nebo třídy, ale ve skutečnosti lze před vrácením nebo přiřazením nové hodnoty poli spustit programový kód, který provede různé druhy kontrol, např. pro platnost nové hodnoty .
    • člen třídy– pole, metody a vlastnosti třídy.
    • Modifikátor přístupudalší funkcečleny třídy, který určuje, zda k nim lze přistupovat z externího programu, nebo zda jsou používány výhradně v rámci hranic třídy a jsou skryty před vnějším světem. Modifikátory přístupu oddělují všechny členy třídy na podrobnosti implementace a veřejné nebo částečně veřejné rozhraní.
    • Konstruktér- speciální metoda, která se spustí ihned po vytvoření instance třídy. Konstruktor inicializuje pole objektu – uvede objekt do výchozího stavu. Konstruktory mohou být buď s parametry, nebo bez nich. Konstruktor bez parametrů se nazývá výchozí konstruktor, který může být pouze jeden. Název metody konstruktoru je nejčastěji stejný jako název samotné třídy.
    • Destruktor- speciální metoda volaná prostředím provádění programu v okamžiku, kdy je objekt odstraněn paměť s náhodným přístupem. Destruktor se používá, když třída obsahuje prostředky, které vyžadují explicitní vydání (soubory, databázová připojení, síťová připojení atd.)
    • Rozhraní- soubor metod a vlastností objektu, které jsou veřejně dostupné a určené k řešení určitého okruhu úloh, například rozhraní pro generování grafického znázornění objektu na obrazovce nebo rozhraní pro uložení stavu objektu v souboru nebo databázi.
    • statický člen– jakýkoli člen třídy, který lze použít bez vytvoření odpovídajícího objektu. Pokud například metoda třídy nepoužívá jediné pole, ale pracuje výhradně s jí předávanými parametry, pak nic nebrání tomu, aby byla použita v kontextu celé třídy, aniž by byly vytvořeny její samostatné instance. Konstanty v kontextu třídy jsou obvykle vždy statické členy třídy.

    Výhody objektově orientovaného programování

    Nyní si povíme něco o vlastnostech, které program získává při použití objektově orientovaného přístupu k jeho návrhu a kódování. Zdá se mi, že většina z těchto vlastností je výhodami OOP, ale existují i ​​​​jiné názory na tuto věc ...

    • Zapouzdření označuje skrytí podrobností implementace tříd odměňováním jejích jednotlivých členů vhodnými modifikátory přístupu. Veškerá funkčnost objektu zaměřená na interakci s jinými objekty programu je tedy seskupena do otevřeného rozhraní a detaily jsou pečlivě skryty uvnitř, což šetří hlavní kód obchodní logiky informačního systému před zbytečnými věcmi. . Zapouzdření zvyšuje provozní spolehlivost programový kód, protože zajišťuje, že určitá data nelze změnit mimo třídu obsahující.
    • Dědictví. Základní kámen OOP. V objektově orientovaném programování je možné zdědit strukturu a chování třídy od jiné třídy. Třída, která je zděděna, se nazývá základní nebo nadtřída a třída, která je získána jako výsledek dědění, se nazývá odvozená nebo pouze potomek. Každá třída může působit jako supertřída i jako dítě. Vztahy dědičnosti tříd tvoří hierarchii tříd. Vícenásobná dědičnost je definice odvozené třídy z několika nadtříd najednou. Ne všechny objektově orientované programovací jazyky podporují vícenásobnou dědičnost. Dědičnost je efektivní způsob, jak izolovat opakovaně použitelné úryvky kódu, ale má i své stinné stránky, o kterých bude řeč později.
    • abstrakce. Schopnost kombinovat třídy do samostatných skupin, zdůrazňovat společné, významné vlastnosti pro všechny z nich (společná pole a společné chování). Ve skutečnosti je abstrakce důsledkem dědičnosti: základní třídy nemají vždy svou vlastní projekci na objekty reálného světa, ale jsou vytvořeny pouze pro zvýraznění společných rysů celé skupiny objektů. Například nábytkový předmět je základním pojmem pro stůl, židli a pohovku, všechny spojuje to, že jde o movitou věc, součást interiéru prostor, a lze je vyrobit do domácnosti nebo kanceláře. a také odkazují na třídu „ekonomická“ nebo „prémiová“. OOP má pro to samostatný koncept – abstraktní třídu – třídu, jejíž objekty nelze vytvořit, ale lze je použít jako základní třídu. Dědičnost a abstrakce umožňují popsat datové struktury programu a vztahy mezi nimi přesně stejným způsobem, jak vypadají odpovídající objekty v uvažovaném doménovém modelu.

    Příklad diagramu tříd sestaveného abstrakcí během analýzy typů stávajících vozidel je znázorněn na následujícím obrázku. Na vyšších úrovních hierarchie dědičnosti jsou abstraktní třídy, které kombinují vozidla podle nejvýznamnějších charakteristik.

    Diagram tříd nebo hierarchie dědičnosti "Vozidla". Bílé čtverce představují abstraktní třídy.

    • Polymorfismus. Další vlastnost, která je důsledkem dědictví. Jde o to, že objektově orientované programovací jazyky umožňují pracovat se sadou objektů ze stejné hierarchie stejným způsobem, jako by to byly všechny objekty jejich základní třídy. Pokud se vrátíme k příkladu o nábytku, pak můžeme předpokládat, že v rámci tvorby informačního systému pro prodejnu nábytku je rozumné přidat do základní třídy pro všechny typy nábytku metodu „ukázat charakteristiky“ společnou všem . Při tisku charakteristik všech druhů zboží by program tuto metodu bez rozdílu volal pro všechny objekty a každý konkrétní objekt by se sám rozhodl, jaké informace mu poskytne. Jak je implementována: Za prvé, v základní třídě je metoda, která je společná všem, definována s chováním společným pro všechny. V případě našeho příkladu se bude jednat o metodu, která vytiskne parametry společné pro jakýkoli typ nábytku. Za druhé, v každé odvozené třídě, kde je to nutné, přepíší základní metodu (přidají metodu se stejným názvem), kde rozšíří základní chování o své vlastní, například zobrazení charakteristik, které jsou charakteristické pouze pro určitý typ nábytku. produkt. Metoda v základní třídě někdy nemusí obsahovat vůbec žádný kód, ale je potřeba pouze k určení názvu a sady parametrů – podpisu metody. Takové metody se nazývají abstraktní metody a třídy, které je obsahují, se automaticky stávají abstraktními třídami. Polymorfismus je tedy možnost jednotné komunikace s objekty různých tříd prostřednictvím určitého rozhraní. Ideologie polymorfismu říká, že abyste mohli komunikovat s objektem, nemusíte znát jeho typ, ale musíte vědět, jaké rozhraní podporuje.
    • Rozhraní. V některých programovacích jazycích (C#, Java) je koncept rozhraní výslovně zdůrazněn – nejde pouze o veřejné metody a vlastnosti samotné třídy. Takové jazyky obecně nepodporují vícenásobnou dědičnost a kompenzují to tím, že umožňují libovolnému objektu mít jeden základní objekt a implementovat libovolný počet rozhraní. Rozhraní v jejich interpretaci je podobné abstraktní třída, obsahující pouze popis (podpis) veřejných metod a vlastností. Implementace rozhraní leží na bedrech každé třídy, která jej bude podporovat. Stejné rozhraní lze implementovat třídami zcela odlišných hierarchií, což rozšiřuje možnosti polymorfismu. Například rozhraní „uložit/obnovit informace v databázi“ může implementovat jak třídy hierarchie „nábytku“, tak třídy spojené s zadáváním zakázek na výrobu nábytku, a když kliknete na tlačítko „uložit“, program by prošel všechny objekty, vyžádal by si od nich toto rozhraní a zavolal by příslušnou metodu.

    Objektově orientované programování se neustále vyvíjí a dává vzniknout novým paradigmatům, jako je aspektově orientované, předmětové a dokonce i agentově orientované programování. Nutno podotknout, že vavříny OOP pronásledují zbytek teoretiků a ti spěchají nabídnout vlastní možnosti, jak jej vylepšit a rozšířit. Prototypování odstraňuje pojem třídy a nahrazuje jej prototypem, instancí objektu. V prototypově orientovaném jazyce tedy neexistuje koncept typu objektu, ale existuje koncept vzorku nebo prototypu. Prototyp je instance objektu, ze kterého se kopírováním (klonováním) jeho členů vytvářejí další instance. V JavaScriptu nepopisujete pole a metody třídy, ale nejprve vytvoříte prázdný objekt a poté k němu přidáte potřebná pole a metody (v JavaScriptu lze metodu definovat a přidat k objektu dynamicky). Podobně vznikají prototypy, které jsou pak ostatními objekty označovány jako jejich prototyp. Pokud objekt nemá nějakou metodu nebo pole, které je uvedeno v místě volání, pak se hledá mezi členy svého prototypu.

    Některé prvky moderního objektově orientovaného programování

    Čas se nezastaví a od příchodu OOP už uplynulo docela dost, takže by nemělo být překvapivé, že se dnes slovní zásoba objektově orientovaného programování vážně rozrostla. Zde jsou některé nové termíny a koncepty související s OOP.

    • Události. Zvláštní druh objektů vytvořených k upozorňování některých objektů na události, ke kterým dochází s jinými objekty. V různých programovacích jazycích je mechanismus událostí implementován různými způsoby: někde pomocí speciálních syntaktických konstrukcí a někde pomocí základních nástrojů OOP.
    • Obecný typ. Koncept generických typů přímo nesouvisí s konceptem OOP, ale je důvodem pro výskyt prvků, jako je generická třída, generická metoda, obecná událost atd. Generický typ je typ parametrizovaný jiným typem (souborem typů). Co je tento typ parametru v kontextu návrhu obecného typu, není známo, i když je možné omezit hodnoty typů parametrů, které mají být odvozeny z konkrétní třídy, nebo implementovat určitá rozhraní. Příkladem je generická třída pro řazení posloupnosti prvků, kde typ prvku v posloupnosti není předem znám. Při navrhování takové třídy je důležité určit, že parametr typu musí podporovat operaci porovnání. Při vytváření objektů generických typů je parametr explicitně specifikován, jako je typ celé číslo nebo řetězec, a samotný objekt se chová, jako by byl instancí třídy vytvořené speciálně pro třídění celých čísel nebo řetězců.
    • Výjimky. Další speciální druh objektu podporovaný vestavěným mechanismem zpracování chyb a výjimek v konkrétním programovacím jazyce. Výjimky kromě kódu chyby obsahují její popis, možné příčiny a zásobník volání metody, který proběhl předtím, než v programu došlo k výjimce.

    Nevýhody objektově orientovaného programování

    Již jsem řekl, že obliba objektově orientovaného přístupu k tvorbě softwarových produktů je obrovská. O tom, že existuje poměrně hodně těch, kteří se snaží toto paradigma rozšířit, jsem již také poznamenal. Existuje však další způsob, jak vyniknout mezi obrovskou komunitou profesionálů v informační technologie je říci, že se OOP neospravedlnila, že není všelékem, ale spíše placebem. Někteří z těchto lidí jsou opravdu odborníci vysoká třída, jako jsou Christopher Date, Alexander Stepanov, Edsger Dijkstra a další, a jejich názor si zaslouží pozornost, ale jsou i tací, o kterých říkají, že „špatnému tanečníkovi vždycky něco vadí“. Zde jsou nejzjevnější nedostatky OOP, na které odborníci upozorňují:

    1. OOP generuje obrovské hierarchie tříd, což vede k tomu, že se funkčnost šíří nebo, jak se říká, rozmazává přes základní a odvozené členy třídy, a je obtížné vysledovat logiku práce konkrétní metody. .

    2. V některých jazycích jsou všechna data objekty, včetně elementárních typů, a to může vést k dalším nákladům na paměť a procesor.

    3. Také rychlost provádění programu může být nepříznivě ovlivněna implementací polymorfismu, který je založen na mechanismech pozdní vazby volání metody s její specifickou implementací v jedné z odvozených tříd.

    4. Psychologický aspekt. Mnoho lidí si myslí, že OOP je cool a začnou jeho přístupy používat kdykoli, kdekoli a bez rozdílu. To vše vede k poklesu produktivity zejména programů a k diskreditaci OOP obecně.

    Java je objektově orientovaný jazyk. To znamená, že Java programy by měly být psány pomocí objektově orientovaného stylu. A tento styl je založen na použití objektů a tříd v programu. Pokusme se pomocí příkladů pochopit, co jsou třídy a objekty, a také jak uvést do praxe základní principy OOP: abstrakci, dědičnost, polymorfismus a zapouzdření.

    Co je to předmět?

    Svět, ve kterém žijeme, se skládá z předmětů. Když se rozhlédneme kolem sebe, uvidíme, že jsme obklopeni domy, stromy, auty, nábytkem, nádobím, počítači. Všechny tyto položky jsou předměty a každý z nich má soubor určitých vlastností, chování a účelu. Jsme zvyklí na předměty a vždy je používáme pro velmi specifické účely. Například když se potřebujeme dostat do práce, používáme auto, když chceme jíst, používáme nádobí, a když si potřebujeme odpočinout, potřebujeme pohodlnou pohovku. Člověk je zvyklý myslet objektivně, aby řešil problémy v běžném životě. To byl jeden z důvodů použití objektů v programování a tento přístup k vytváření programů byl nazýván objektově orientovaný. Vezměme si příklad. Představte si, že jste se vyvinuli nový model telefon a chtějí zahájit jeho sériovou výrobu. Jako návrhář telefonu víte, k čemu slouží, jak bude fungovat a z jakých částí se bude skládat (pouzdro, mikrofon, reproduktor, kabely, tlačítka atd.). V tomto případě pouze vy víte, jak tyto části spojit. Neplánujete však vyrábět telefony osobně, na to máte celý štáb zaměstnanců. Abyste nemuseli pokaždé vysvětlovat, jak zapojit části telefonu, a aby všechny telefony při výrobě dopadly stejně, budete si muset udělat nákres ve formě popisu zařízení telefonu před jsou propuštěni. V OOP se takový popis, výkres, diagram nebo šablona nazývá třída, ze které se při spuštění programu vytvoří objekt. Třída je popis objektu, který ještě nebyl vytvořen, jako by obecná šablona sestávající z polí, metod a konstruktoru a objekt je instancí třídy vytvořené na základě tohoto popisu.

    Abstrakce

    Pojďme se nyní zamyslet nad tím, jak můžeme přejít od objektu v reálném světě k objektu v programu pomocí telefonu jako příkladu. Historie tohoto komunikačního prostředku přesahuje 100 let a moderní telefon je na rozdíl od svého předchůdce z 19. století mnohem složitějším zařízením. Když používáme telefon, nemyslíme na jeho strukturu a procesy, které se v něm odehrávají. Jednoduše používáme funkce poskytnuté vývojáři telefonu – tlačítka nebo dotykový displej pro výběr čísla a volání. Jedním z prvních telefonních rozhraní byla klika, kterou bylo nutné otáčet, aby bylo možné uskutečnit hovor. To samozřejmě nebylo příliš pohodlné. Přesto rukojeť plnila svou funkci správně. Pokud se podíváte na nejmodernější a vůbec první telefon, můžete okamžitě vyzdvihnout nejdůležitější detaily, které jsou důležité jak pro zařízení konce 19. století, tak pro ultramoderní smartphone. Jedná se o uskutečnění hovoru (vytáčení) a přijetí hovoru. V podstatě to je to, co dělá telefon telefonem, a ne něco jiného. Nyní jsme v OOP uplatnili princip – zvýraznění nejvíce důležité vlastnosti a informace o objektu. Tento princip se nazývá abstrakce. Abstrakce v OOP může být také definována jako způsob reprezentace prvků úlohy z reálného světa jako objektů v programu. Abstrakce je vždy spojena se zobecněním některých informací o vlastnostech objektů či objektů, jde tedy především o oddělení významných informací od nepodstatných v kontextu řešeného problému. Může existovat několik úrovní abstrakce. Zkusme aplikovat princip abstrakce na naše telefony. Pro začátek si ukažme nejběžnější typy telefonů od prvních až po současnost. Mohou být například znázorněny ve formě diagramu znázorněného na obrázku 1. Nyní pomocí abstrakce můžeme v této hierarchii objektů vybrat obecná informace: obecný abstraktní typ objektu - telefon, obecné charakteristiky telefon - rok svého vzniku a společné rozhraní - všechny telefony jsou schopny přijímat a odesílat hovory. V Javě to vypadá takto: veřejná abstraktní třída AbstractPhone ( private int year; public AbstractPhone (int year) ( this . year = year; ) public abstract void call (int outputNumber) ; public abstract void ring (int inputNumber) ; ) Na základě této abstraktní třídy budeme moci v programu vytvářet nové typy telefonů s využitím dalších základních Java OOP principů, o kterých se budeme bavit níže.

    Zapouzdření

    Používáním abstrakce přidělujeme Všeobecné pro všechny předměty. Každý model telefonu je však individuální a poněkud odlišný od ostatních. Jak můžeme v programu vymezit hranice a označit tuto individualitu? Jak zajistit, aby nám nikdo z uživatelů nemohl náhodně či úmyslně rozbít telefon, nebo se pokusit předělat jeden model na jiný? Pro svět skutečných předmětů je odpověď zřejmá: všechny detaily musíte vložit do pouzdra na telefon. Ostatně, pokud se to neudělá a všechny vnitřnosti telefonu a vodiče, které je spojují, zůstanou venku, určitě se najde zvídavý experimentátor, který bude chtít fungování našeho telefonu „vylepšit“. K vyloučení takového zásahu do návrhu a provozu objektu používá OOP princip zapouzdření - jiný základní princip OOP, ve kterém jsou atributy a chování objektu kombinovány v jedné třídě, vnitřní implementace objektu je skryta před uživatelem a pro práci s objektem je poskytnuto veřejné rozhraní. Úkolem programátora je určit, které atributy a metody budou dostupné pro veřejný přístup a které jsou vnitřní implementací objektu a neměly by být měněny.

    Zapouzdření a kontrola přístupu

    Například při výrobě jsou na zadní straně telefonu vyryty informace o něm: rok vydání nebo logo společnosti výrobce. Tato informace zcela konkrétně charakterizuje tento model – jeho stav. Dá se říci, že se vývojář telefonu postaral o neměnnost těchto informací – je nepravděpodobné, že by někoho napadlo rytinu odstranit. Ve světě Java je stav budoucích objektů popsán ve třídě pomocí polí a jejich chování je popsáno pomocí metod. Schopnost změnit stav a chování se provádí pomocí modifikátorů přístupu k polím a metodám - soukromý, chráněný, veřejný , a výchozí (výchozí přístup). Rozhodli jsme se například, že rok vytvoření, jméno výrobce telefonu a jedna z metod patří do interní implementace třídy a nelze je měnit jinými objekty v programu. Pomocí kódu lze třídu popsat takto: public class SomePhone ( private int year; private String company; public SomePhone (int year, String company) ( this . year = year; this . company = company; ) private void openConnection ( ) ( / /findComutator //openNewConnection... ) public void call () ( openConnection () ; System. out. println ("Volání čísla") ; ) public void ring () ( System. out. println ("Ring prsten"); ) ) Modifikátor soukromé zpřístupňuje pole a metody třídy pouze v rámci této třídy. To znamená, že přístup k soukromé pole zvenčí to nejde, stejně tak není možnost se dovolat soukromé metody. Skrytí přístupu k metodě openConnection nám také ponechává volnost změnit vnitřní implementaci této metody, protože tuto metodu zaručeně nepoužijí jiné objekty a nenaruší jejich práci. Pro práci s naším objektem necháme otevřené metody volání a vyzvánění pomocí modifikátoru veřejnost . Poskytování veřejných metod pro práci s objektem je také součástí mechanismu zapouzdření, takže pokud zcela zavřete přístup k objektu, stane se zbytečným.

    Dědictví

    Podívejme se znovu na schéma telefonu. Vidíte, že jde o hierarchii, ve které má níže uvedený model všechny vlastnosti modelů výše ve větvi a navíc své vlastní. Například chytrý telefon, který ke komunikaci využívá celulární síť (má vlastnosti mobilního telefonu), je bezdrátový a přenosný (má vlastnosti bezdrátového telefonu) a může přijímat a volat (vlastnosti telefonu). V tomto případě můžeme mluvit o dědičnosti vlastností objektu. V programování je dědičnost použití existujících tříd k popisu nových. Zvažte příklad vytvoření třídy smartphonu pomocí dědičnosti. Všechny bezdrátové telefony fungují na dobíjecích bateriích, které mají určitou životnost v hodinách. Přidejme tedy tuto vlastnost do třídy bezdrátového telefonu: veřejná abstraktní třída WirelessPhone rozšiřuje AbstractPhone ( private int hour; public WirelessPhone (int year, int hour) ( super (year) ; this . hour = hour; ) ) přidali jsme také implementaci z metod volání a vyzvánění do této třídy: public class CellPhone rozšiřuje WirelessPhone ( public CellPhone (int year, int hour) ( super (year, hour) ; ) @Override public void call (int outputNumber) ( System. out. println ( "Calling number" + outputNumber) ; ) @Override public void ring (int inputNumber) ( System. out. println ( "Volá vám předplatitel"+ inputNumber); ) ) A nakonec třída smartphonů, která na rozdíl od klasických mobilů disponuje plnohodnotným operačním systémem. Do smartphonu můžete přidat nové aplikace podporované tímto smartphonem. operační systémčímž se rozšíří jeho funkčnost. Pomocí kódu lze třídu popsat následovně: public class Smartphone rozšiřuje Mobilní telefon ( private String operationSystem; public Smartphone (int year, int hour, String operationSystem) ( super (year, hour) ; this . operationSystem = operationSystem; ) public void install (String program) ( System. out. println ("Nastavil jsem " + program + " pro" + operationSystem) ; ) ) Jak můžete vidět, vytvořili jsme docela dost nového kódu pro popis třídy Smartphone, ale dostali jsme nová třída s novými funkcemi. Použití tohoto principu OOP java umožňuje výrazně snížit množství kódu, a tím usnadnit programátorovi.

    Polymorfismus

    Pokud se podíváme na všechny modely telefonů, tak i přes rozdíly ve vzhledu a designu modelů u nich můžeme rozlišit některé běžné chování – všechny umí přijímat i volat a mají celkem přehlednou a jednoduchou sadu ovládacích tlačítek. Aplikováním jednoho ze základních principů OOP, abstrakce z hlediska programování, která je nám již známá, můžeme říci, že objekt telefonu má jedno společné rozhraní. Uživatelé telefonů tak mohou celkem pohodlně používat různé modely pomocí stejných ovládacích tlačítek (mechanických nebo dotykových), aniž by zacházeli do technických detailů zařízení. Takže neustále používáte mobilní telefon a můžete snadno volat z jeho protějšku z pevné linky. Volá se princip v OOP, kdy program může používat objekty se stejným rozhraním, aniž by věděl o vnitřní struktuře objektu polymorfismus . Představme si, že potřebujeme v programu popsat uživatele, který může pomocí libovolného modelu telefonu zavolat jinému uživateli. Zde je návod, jak to udělat: public class User ( private String name; public User (String name) ( this . name = name; ) public void callAnotherUser (int number, AbstractPhone phone) ( // zde je to polymorfismus - použití abstraktního typu telefonu AbstractPhone v kódu! telefon. telefonní číslo) ; ) ) ) Nyní si popišme různé modely telefonů. Jeden z prvních modelů telefonů: public class ThomasEdisonPhone rozšiřuje AbstractPhone ( public ThomasEdisonPhone (int year) ( super (year) ; ) @Override public void call (int outputNumber) ( System. out. println("Otočte knoflíkem" ) ; System . out .println( "Dejte mi telefonní číslo, pane"); ) @Override public void ring (int inputNumber) ( System. out. println ("Telefon zvoní") ; ) ) Běžný pevný telefon: veřejná třída Telefon prodlužuje AbstraktTelefon ( public Phone (int year) ( super (year) ; ) @ Přepsat veřejné volání void (int outputNumber) ( System. out. println ("Volám číslo" + outputNumber) ; ) @Override public void ring (int inputNumber) ( System. out. println ("Telefon zvoní"" ) ;) "Připojuji videokanál pro odběratele"+ výstupní číslo); ) @Override public void ring(int inputNumber)( System.out.println( "Máte příchozí videohovor..."+ inputNumber); ) ) Vytvořte objekty v metodě main() a otestujte metodu callAnotherUser: AbstractPhone firstPhone = new ThomasEdisonPhone (1879 ) ; AbstractPhone phone = new Phone(1984) ; AbstractPhone videoPhone= nový VideoTelefon (2018) ; Uživatel uživatel = nový uživatel("Andrey" ) ; uživatel. volání Jiný uživatel (224466, první telefon) ; // Otáčejte knoflíkem // Řekněte mi číslo předplatitele, pane uživatel. zavolat Jiný uživatel (224466 , telefon) ; //Volejte na číslo 224466 uživatel. callAnotherUser (224466 , videoPhone) ; //Připojuji videokanál pro odběratele 224466 Voláním stejné metody na objekt uživatele jsme získali různé výsledky. Volba konkrétní implementace metody volání uvnitř metody callAnotherUser byla provedena dynamicky na základě specifického typu objektu, který ji volal během provádění programu. To je hlavní výhoda polymorfismu - volba implementace během provádění programu. Ve výše uvedených příkladech třídy telefonu jsme použili přepis metody, techniku, která mění implementaci metody definovanou v základní třídě, aniž by se změnil podpis metody. Toto je v podstatě náhrada metody a je to nová metoda definovaná v podtřídě, která je volána při spuštění programu. Obvykle se při přepisování metody používá anotace @Override, která říká kompilátoru, aby zkontroloval signatury přepsaných a přepisujících metod. Nakonec Chcete-li stylizovat svůj program podle konceptu OOP a principů java OOP, postupujte podle těchto tipů:
    • zvýraznit hlavní charakteristiky objektu;
    • zvýraznění společných vlastností a chování a použití dědičnosti při vytváření objektů;
    • používat abstraktní typy k popisu objektů;
    • pokuste se vždy skrýt metody a pole související s vnitřní implementací třídy.

    Pravděpodobně je u poloviny volných míst (ne-li více) vyžadována znalost a porozumění OOP. Ano, tato metodika rozhodně uchvátila mnoho programátorů! Pochopení OOP obvykle přichází se zkušenostmi, protože na toto téma prakticky neexistují žádné vhodné a dostupné materiály. A i kdyby ano, není zdaleka pravda, že na ně čtenáři narazí. Doufám, že se mi podaří vysvětlit principy této nádherné metodiky, jak se říká, na prstech.

    Již na začátku článku jsem tedy již zmínil pojem „metodika“. Ve vztahu k programování tento termín implikuje existenci jakékoli sady způsobů, jak organizovat kód, metody jeho psaní, po kterých bude programátor schopen psát docela vhodné programy.

    OOP (neboli objektově orientované programování) je způsob organizace programového kódu, kdy hlavními stavebními kameny programu jsou objekty a třídy a logika programu je postavena na jejich interakci.


    O objektech a třídách

    Třída- to je taková datová struktura, kterou si může vytvořit sám programátor. Z hlediska OOP se třída skládá z pole(jednoduchým způsobem - proměnné) a metody(jednoduchým způsobem - funkce). A jak se ukázalo, kombinace dat a funkcí práce s nimi v jedné struktuře dává nepředstavitelnou sílu. Objekt je konkrétní instancí třídy. V souladu s analogií třídy s datovou strukturou je objekt konkrétní datová struktura, jejíž pole mají přiřazeny nějaké hodnoty. Dovolte mi to vysvětlit na příkladu:

    Řekněme, že potřebujeme napsat program, který vypočítá obvod a plochu trojúhelníku se dvěma stranami a úhlem mezi nimi. K napsání takového programu pomocí OOP budeme potřebovat vytvořit třídu (tedy strukturu) Triangle. Třída Triangle uloží tři pole (tři proměnné): strana A, strana B, úhel mezi nimi; a dvě metody (dvě funkce): vypočítat obvod, vypočítat plochu. Pomocí této třídy můžeme popsat libovolný trojúhelník a vypočítat obvod a plochu. Takže konkrétní trojúhelník se specifickými stranami a úhlem mezi nimi se bude nazývat instancí třídy Triangle. Třída je tedy šablona a instance je konkrétní implementací šablony. Ale již instance jsou objekty, tedy konkrétní prvky, které ukládají konkrétní hodnoty.

    Java je jedním z nejrozšířenějších objektově orientovaných programovacích jazyků. Bez použití předmětů se to prostě neobejde. Zde je návod, jak by vypadal kód třídy popisující trojúhelník v tomto jazyce:

    /** * Třída Triangle. */ class Triangle ( /** * Speciální metoda zvaná konstruktor třídy. * Jako vstup bere tři parametry: * délku strany A, délku strany B, * úhel mezi těmito stranami (ve stupních) */ Triangle(double sideA, double sideB , double angleAB) ( this.sideA = sideA; this.sideB = sideB; this.angleAB = angleAB; ) double sideA; //Pole třídy, uloží hodnotu strany A do popsaného trojúhelníku double stranaB; //Pole třídy, ukládá hodnotu strany B v popsaném trojúhelníku double angleAB; //Pole třídy, které ukládá úhel (ve stupních) mezi dvěma stranami v popsaném trojúhelníku /** * Metoda třídy, která počítá plochu ​​trojúhelník */ double getSquare() ( double square = this.sideA * this .sideB * Math.sin(this.angleAB * Math.PI / 180); return square; ) /** * Metoda třídy, která počítá obvod trojúhelníku */ double getPerimeter() ( double sideC = Math.sqrt(Math.pow (this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math .cos(tento.uhelAB * Math.PI / 180)); dvojitý obvod = tato.stranaA + tato.stranaB + stranaC; návratový obvod; ))

    Pokud do třídy přidáme následující kód:

    /** * Zde začíná program */ public static void main(String args) ( //Hodnoty ​​5, 17, 35 jdou do konstruktoru třídy Triangle Triangle trojúhelník1 = new Triangle(5, 17, 35); System.out .println("Oblast trojúhelníku1: "+trojúhelník1.getSquare()); System.out.println("Obvod trojúhelníku1: "+trojúhelník1.getPerimeter()); //Hodnoty 6, 8, 60 přejděte na konstruktor třídy Triangle Triangle trojúhelník2 = new Triangle(6, 8, 60); System.out.println("Oblast trojúhelníku1: "+trojúhelník2.getSquare()); System.out. println("Obvod trojúhelníku1: "+trojúhelník2.getPerimeter()); )

    pak již může být program spuštěn ke spuštění. Je to vlastnost jazyk java. Pokud má třída takovou metodu

    public static void main (string args)

    pak lze tuto třídu spustit. Pojďme analyzovat kód podrobněji. Začněme čárou

    Trojúhelník trojúhelník1 = nový Trojúhelník(5, 17, 35);

    Zde vytvoříme instanci trojúhelníku1 třídy Triangle a hned jí přidělíme parametry stran a úhel mezi nimi. Současně se zavolá speciální metoda zvaná konstruktor a vyplní pole objektu hodnotami předanými konstruktoru. No, čáry

    System.out.println("Oblast trojúhelníku1: "+trojúhelník1.getSquare()); System.out.println("Obvod trojúhelníku1: "+trojúhelník1.getPerimetr());

    odešlete vypočítanou plochu trojúhelníku a jeho obvod na konzolu.

    Podobně se vše děje pro druhou instanci třídy Triangle.

    Pochopení podstaty tříd a konstrukce konkrétní objekty je solidním prvním krokem k pochopení metodologie OOP.

    Ještě jednou to nejdůležitější:

    OOP je způsob organizace programového kódu;

    Třída- jedná se o vlastní datovou strukturu, která kombinuje data a funkce pro práci s nimi (pole tříd a metody tříd);

    Objekt je specifická instance třídy, jejíž pole jsou nastavena na konkrétní hodnoty.


    Tři kouzelná slova

    OOP zahrnuje tři klíčové přístupy: dědičnost, zapouzdření a polymorfismus. Za prvé, zde jsou definice z wikipedie:

    Encapsulation je systémová vlastnost, která umožňuje kombinovat data a metody, které s nimi pracují, ve třídě. Některé jazyky (například C++) přirovnávají zapouzdření ke skrytí, ale většina (Smalltalk, Eiffel, OCaml) tyto pojmy rozlišuje.

    Dědičnost je systémová vlastnost, která vám umožňuje popsat novou třídu na základě existující třídy s částečně nebo zcela vypůjčenou funkčností. Třída, ze které dědíte, se nazývá základní, nadřazená nebo nadřazená třída. Nová třída je potomkem, následníkem, potomkem nebo odvozenou třídou.

    Polymorfismus je vlastnost systému, která umožňuje používat objekty se stejným rozhraním bez informací o typu a vnitřní struktuře objektu.

    Je poměrně obtížné pochopit, co všechny tyto definice v praxi znamenají. Ve specializovaných knihách, které toto téma pokrývají, má každá definice často celou kapitolu, ale minimálně odstavec. I když existuje jen velmi málo podstaty toho, co je třeba pochopit a navždy vtisknout do mozku vašeho programátora.
    A postavy v letadle poslouží jako příklad pro analýzu. Ze školní geometrie víme, že u všech obrazců popsaných na rovině je možné vypočítat obvod a plochu. Například pro bod jsou oba parametry nulové. U segmentu můžeme vypočítat pouze obvod. A pro čtverec, obdélník nebo trojúhelník - obojí. Nyní popíšeme tento problém z hlediska OOP. Je také užitečné zachytit řetězec uvažování, který vede k hierarchii tříd, která je zase ztělesněna v pracovním kódu. Jít:


    Tečka je tedy nejmenší geometrický obrazec, který je základem všech ostatních konstrukcí (obrázků). Proto je bod vybrán jako základní rodičovská třída. Pojďme napsat bodovou třídu v jazyce Java:

    /** * Bodová třída. Základní třída */ class Point ( /** * Prázdný konstruktor */ Point() () /** * Metoda třídy, která vypočítá plochu obrázku */ double getSquare() ( return 0; ) /** * Metoda třídy, která vypočítá obvod obrázku */ double getPerimeter() ( return 0; ) /** * Metoda třídy, která vrátí popis obrázku */ String getDescription() ( return "Point"; ) )

    Výsledná třída Point má prázdný konstruktor, protože in tento příklad pracujeme bez konkrétních souřadnic a pracujeme pouze s parametry - hodnotami stran. Protože bod nemá žádné strany, není třeba mu předávat žádné parametry. Všimněte si také, že třída má metody Point::getSquare() a Point::getPerimeter() pro výpočet plochy a obvodu, obě vrací 0. Pro bod je to logické.


    Protože náš bod je základem všech ostatních obrazců, dědíme třídy těchto dalších obrazců ze třídy Point. Popišme třídu segmentů zděděnou z třídy bodů:

    /** * Třída segmentu */ class LineSegment extends Point ( LineSegment(double segmentLength) ( this.segmentLength = segmentLength; ) double segmentLength; // Délka segmentu /** * Přepsaná metoda třídy, která vypočítá plochu segmentu */ double getSquare( ) ( return 0; ) /** * Přepsaná metoda třídy, která vypočítá obvod segmentu */ double getPerimeter() ( return this.segmentLength; ) String getDescription() ( return "Délka segmentu: " + this.segmentLength; ) )

    Třída LineSegment rozšiřuje Point

    znamená, že třída LineSegment dědí z třídy Point. Metody LineSegment::getSquare() a LineSegment::getPerimeter() přepisují odpovídající metody základní třídy. Plocha segmentu je vždy rovna nule a plocha obvodu se rovná délce tohoto segmentu.

    Nyní, stejně jako třídu segmentů, popišme třídu trojúhelníku (která také dědí z třídy bodů):

    /** * Třída Triangle. */ class Triangle extends Point ( /** * Class konstruktor. Jako vstup bere tři parametry: * délka strany A, délka strany B, * úhel mezi těmito stranami (ve stupních) */ Triangle(double sideA, double sideB) , double angleAB ) ( this.sideA = sideA; this.sideB = sideB; this.angleAB = angleAB; ) double sideA; //Pole třídy, uloží hodnotu strany A do popsaného trojúhelníku double sideB; //Pole třídy, ukládá hodnotu strany B do popsaného trojúhelníku trojúhelník double angleAB; //Pole třídy, které ukládá úhel (ve stupních) mezi dvěma stranami v popsaném trojúhelníku /** * Metoda třídy, která počítá obsah trojúhelníku */ double getSquare() ( double square = (this.sideA * this.sideB * Math.sin(this.angleAB * Math.PI / 180)))/2; return square; ) /** * Metoda třídy, která vypočítává obvod trojúhelník */ double getPerimeter() ( double sideC = Math.sqrt(Math. pow(this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math. cos(tento.uhelAB * Math.PI / 180)); dvojitý obvod = tato.stranaA + tato.stranaB + stranaC; návratový obvod; ) String getDescription() ( return "Trojúhelník se stranami: " + this.sideA + ", " + this.sideB + " a úhel mezi nimi: " + this.angleAB; ) )

    Není zde nic nového. Také metody Triangle::getSquare() a Triangle::getPerimeter() přepisují odpovídající metody základní třídy.
    No a teď ve skutečnosti samotný kód, který ukazuje kouzlo polymorfismu a odhaluje sílu OOP:

    Class Main ( /** * Zde začíná program */ public static void main(String args) ( //ArrayList je speciální datová struktura v jazyce Java, která // umožňuje ukládat objekty určitého typu do pole. ArrayList figure = new ArrayList (); //přidání tří různých objektů k figurám pole figure.add(new Point()); Figure.add(new LineSegment(133)); Figure.add(new Triangle(10, 17, 55)); pro (int i = 0; i

    Vytvořili jsme pole objektů třídy Point, a protože třídy LineSegment a Triangle jsou zděděny z třídy Point, můžeme je do tohoto pole vložit také. Ukazuje se, že každou postavu, která je v poli figurek, můžeme považovat za objekt třídy Point. O tom je polymorfismus: není známo, do jaké třídy objekty v poli figurek patří, ale protože všechny objekty v tomto poli patří do stejné základní třídy Point, všechny metody, které se vztahují na třídu Point, platí také pro její potomkové třídy.


    Nyní o zapouzdření. Skutečnost, že jsme umístili parametry obrázku a metody pro výpočet plochy a obvodu do jedné třídy, je to, co je zapouzdření, zapouzdřili jsme obrázky do samostatných tříd. To, že ve třídě používáme pro výpočet perimetru speciální metodu, je zapouzdření, výpočet obvodu jsme zapouzdřili v metodě getPerimiter(). Jinými slovy, zapouzdření je skrytí implementace (možná nejkratší a zároveň prostorná definice zapouzdření).


    Celý příklad kódu:

    Importovat java.util.ArrayList; class Main ( /** * Zde začíná program */ public static void main(String args) ( //ArrayList je speciální datová struktura v jazyce Java, která // umožňuje ukládat objekty určitého typu do pole. ArrayList figure = new ArrayList (); //přidání tří různých objektů k figurám pole figure.add(new Point()); Figure.add(new LineSegment(133)); Figure.add(new Triangle(10, 17, 55)); pro (int i = 0; i