Co je OOP s příklady. Pro figuríny

(OOP) organizuje data a algoritmy zpracovávané programem. V tomto případě programátor vytváří datové formy a algoritmy, které odpovídají hlavním charakteristikám řešeného problému. Nazývají se datové modely a algoritmy, které je zpracovávají třídy, A objektů- jedná se o jejich konkrétní zástupce použité v programu.

Z obecných objektů vznikají další, specializovanější. Mechanismus pro vytváření takových podobjektů se nazývá dědictví. V důsledku toho jsou tyto programy objektový model- strom objektů, počínaje nejvyšším nejabstraktnějším a nejobecnějším objektem.

OOP kombinuje nejlepší principy strukturovaného programování s výkonnými novými koncepty, z nichž základní se nazývají zapouzdření, polymorfismus a dědičnost.

Příkladem objektově orientovaných jazyků jsou: Object Pascal , C++, Java.

OOP vám umožňuje optimálně organizovat programy rozdělením problému na jednotlivé části a prací s každou zvlášť.

Objektově orientované programování je vývoj technologie strukturovaného programování, ale má své charakteristické rysy. Základní jednotkou v objektově orientovaném programování je objekt, který obsahuje a zapouzdřuje jak data, která jej popisují (vlastnosti), tak prostředky pro zpracování těchto dat (metody). Systémy OOP obvykle používají grafické rozhraní k vizualizaci procesu programování. Pomocí myši je možné vytvářet objekty, nastavovat jejich vlastnosti a chování.

Objekt je kombinací dat a kódu. Jinými slovy, objekt také tzv zástupce(některé třídy) je kus dat, jehož hodnota určuje jeho aktuální stav, a soubor podprogramů tzv. metody pracovat s těmito daty a definovat chování objekt, tzn. jeho reakce na vnější vlivy.

Objekt se skládá ze tří částí:

Název objektu;

Stav (stavové proměnné);

Metody (operace).

Každý objekt je zástupcem (instancí) určitého třída. Během provádění programu objekty vzájemně interagují voláním metod, což jsou podprogramy specifické pro určitou třídu.

Třída(třída) je skupina dat a metod (funkcí) pro práci s těmito daty. Toto je šablona. Objekty se stejnými vlastnostmi, tedy se stejnými sadami stavových proměnných a metod, tvoří třídu. Objekt je konkrétní implementace, instance třídy. V programování lze vztah mezi objektem a třídou přirovnat k popisu proměnné, kde samotná proměnná (objekt) je instancí nějakého datového typu (třídy).


Objektově orientované programování spočívá ve vytvoření určitého počtu tříd, popisu vztahů mezi těmito třídami a jejich vlastnostmi a následné implementaci výsledných tříd.

Teoretický přístup. Třída je jednou z možností popisu entity, která se v teorii programování nazývá abstraktní datový typ. Třída definuje skrytou vnitřní strukturu hodnoty a také sadu operací, které lze na tuto hodnotu použít.

Praktický přístup. V moderních objektově orientovaných programovacích jazycích (php, Java, C++, Oberon, Python, Ruby, Smalltalk, Object Pascal) tvorba třídy spočívá v psaní struktury obsahující sadu polí a metod. V praxi lze třídu chápat jako jakousi šablonu, podle které se vytvářejí objekty – instance dané třídy. Instance stejné třídy jsou vytvořeny pomocí stejné šablony, a proto mají stejnou sadu polí a metod.

Vztahy mezi třídami:

Dědičnost (zobecnění) - objekty podřízené třídy dědí všechny vlastnosti nadřazené třídy.

Asociace - objekty tříd se vzájemně ovlivňují.

Agregace - objekty jedné třídy jsou zahrnuty do objektů jiné.

Kompozice - objekty jedné třídy jsou zahrnuty do objektů druhé a vzájemně na sobě závisí z hlediska jejich životnosti.

Třída-Metatřída je vztah, ve kterém jsou ostatní třídy instancemi jedné třídy.

Typy tříd:

Základní (rodičovská) třída;

Odvozená třída (nástupce, potomek);

Abstraktní třída;

Virtuální třída;

Rozhraní.

Třída je strukturální datový typ, který zahrnuje popis datových polí a také procedury a funkce, které s těmito datovými poli pracují. Ve vztahu ke třídám se takové procedury a funkce nazývají metody.

Metody- procedury a funkce zapouzdřené ve třídě, tedy způsoby práce s daty.

Třídy a objektově orientované programování jsou založeny na třech principech: - zapouzdření, dědictví A polymorfismus.

Zapouzdření(hiding) je vlastnost programovacího jazyka, která umožňuje kombinovat data a kód do objektu a skrýt implementaci objektu před uživatelem. V tomto případě je uživateli poskytnuta pouze specifikace (rozhraní) objektu. Uživatel může s objektem komunikovat pouze prostřednictvím tohoto rozhraní.

Nejčastěji se zapouzdření provádí skrýváním informací, to znamená maskováním všech vnitřních detailů, které neovlivňují vnější chování. Obvykle je skryta jak vnitřní struktura objektu, tak implementace jeho metod.

Cíle zapouzdření:

§ extrémní lokalizace změn, pokud jsou takové změny nutné,

§ předvídatelnost změn (jaké změny v kódu je potřeba provést pro danou změnu funkčnosti) a předvídatelnost důsledků změn.

Zapouzdření- jedná se o proces vzájemného oddělení prvků objektu, které určují jeho strukturu a chování. Zapouzdření lze často dosáhnout jednoduchými organizačními opatřeními: vědomí, že „toto není něco, co nemůžete udělat“, je někdy nejúčinnějším prostředkem zapouzdření!

Zapouzdření- spojením záznamů s procedurami a funkcemi, které manipulují s poli těchto záznamů, vzniká nový datový typ - objekt.

Zapouzdření- izolace komponent třídy (polí, metod a vlastností) od ostatních částí programu.

Podstata zapouzdření: Stavové proměnné objektu jsou před vnějším světem skryté. Změna stavu objektu (jeho proměnných) je možná POUZE pomocí jeho metod (operací). Proč je to tak důležité? Tento princip umožňuje chránit stavové proměnné objektu před zneužitím.

Použití této metody vede ke snížení efektivity přístupu k objektovým prvkům. To je způsobeno nutností volat metody pro změnu vnitřních prvků (proměnných) objektu. Při současném stupni rozvoje výpočetní techniky však tyto ztráty na účinnosti nehrají významnou roli.

Dědictví- jeden ze čtyř nejdůležitějších mechanismů objektově orientovaného programování (spolu se zapouzdřením, polymorfismem a abstrakcí), který umožňuje popsat novou třídu na základě již existující (rodičovské), přičemž vlastnosti a funkčnost nadřazené třídy jsou zapůjčené novou třídou.

Dědictví- je to proces, při kterém může jeden objekt zdědit vlastnosti jiného objektu a přidat k nim vlastnosti charakteristické pouze pro něj. Smysl a univerzálnost dědičnosti spočívá v tom, že nemusíte pokaždé popisovat nový objekt (od nuly), ale můžete zadat rodiče (základní třídu) a popsat charakteristické rysy nové třídy. Výsledkem je, že nový objekt bude mít všechny vlastnosti nadřazené třídy plus své vlastní charakteristické rysy.

Dědictví- představuje možnost konstrukce hierarchie objektů pomocí dědičnosti jejich vlastností.

Dědictví. Dědičnost je vlastnost objektu, která mu umožňuje používat pole a metody nadřazeného objektu, aniž by je popisoval ve své struktuře.

Dědictví- schopnost vytvářet nové třídy založené na existujících s možností používat jejich komponenty. Objekt patřící do podřízené třídy může používat pole, vlastnosti a metody rodičovské třídy a nové komponenty její třídy.

Pokud je v podřízené třídě popsána nová metoda stejného jména jako metoda nadřazené třídy, říká se, že nadřazená metoda je v potomku „přepsána“. Jinými slovy, podřízená třída implementuje specifikaci již existující třídy (základní třídy). To vám umožní zacházet s objekty podřízené třídy stejným způsobem jako s objekty základní třídy. Při vytváření hierarchie tříd se některé vlastnosti objektů při zachování jmen v podstatě mění.

Pro implementaci takových hierarchií poskytuje programovací jazyk polymorfismus. Slovo polymorfismus je řeckého původu a překládá se jako „má mnoho podob“.

Polymorfismus. Přiřazení jednoho názvu akci, která je pak sdílena dolů a nahoru v hierarchii objektů, přičemž každý objekt v hierarchii provádí tuto akci způsobem, který mu vyhovuje.

Polymorfismus je vlastnost, která umožňuje použití stejného názvu k řešení několika technicky odlišných problémů.

Z hlediska OOP můžeme říci, že všechny typy tlačítek rozhraní mají schopnost zobrazovat se na obrazovce. Způsob (postup) je však pro každý typ tlačítka jiný. Na obrazovku se nakreslí jednoduché tlačítko postupem „zobrazení obrázku jednoduchého tlačítka“, přepínací tlačítko se na obrazovku nakreslí postupem „zobrazení obrázku tlačítka přepínače“ atd.

Existuje tedy jediná akce pro celý seznam tlačítek rozhraní (zobrazení obrázku tlačítka na obrazovce), která je implementována způsobem specifickým pro každé tlačítko. To je projev polymorfismu.

Polymorfismus- schopnost tříd řešit podobné problémy různými způsoby. Když je nadřazená metoda přepsána, je do potomka implementován nový algoritmus pro řešení problému. Ukazuje se, že v nadřazeném objektu a podřízeném objektu existují dvě metody stejného jména, které mají odlišný algoritmický základ.

Polymorfismus- jedná se o metodu jednání se sadou objektů stejného předka v jednom kroku, bez upřesňování operací s každým konkrétním objektem. Je také základem rozšiřitelnosti objektově orientovaných programů, protože umožňuje starším programům přijímat nové datové typy, které nebyly definovány při psaní programu.

V obecném smyslu je pojem polymorfismus myšlenkou „jednoho rozhraní, mnoha metod“. To znamená, že můžete vytvořit společné rozhraní pro skupinu souvisejících akcí.

Výhoda Polymorfismus spočívá v tom, že pomáhá snižovat složitost programu tím, že umožňuje použití jediného rozhraní pro jednu třídu akcí. Výběr konkrétní akce v závislosti na situaci spočívá na kompilátoru.

V OOP je cílem polymorfismu použít jeden název k definování akcí společných pro třídu. V praxi to znamená možnost objektů vybrat si vnitřní proceduru (metodiku) na základě typu dat přijatých ve zprávě.

Mechanismus provozu OOP v takových případech lze popsat asi takto: při volání té či oné metody třídy se nejprve hledá metoda samotné třídy. Pokud je metoda nalezena, je provedena a hledání této metody končí. Pokud metoda není nalezena, pak se obrátíme na nadřazenou třídu a hledáme na ní volanou metodu. Pokud je nalezen, postupujeme, jako bychom našli metodu v samotné třídě. A pokud ne, pokračujeme v dalším prohledávání hierarchického stromu. Až do kořene (nejvyšší třídy) hierarchie.

Základní principy a fáze objektově orientovaného

programování

V teorii programování je OOP definována jako technologie pro vytváření komplexního softwaru, která je založena na reprezentaci programu jako kolekce objektů, z nichž každý je instancí určitého typu (třídy) a třídy tvoří hierarchii s

dědění vlastností.

Interakce softwarových objektů v takovém systému se provádí předáváním zpráv.

Poznámka. Tato reprezentace programu byla poprvé použita v simulačním jazyce pro komplexní systémy Simula, který se objevil již v 60. letech.

Způsob reprezentace programu, který je pro modelovací jazyky přirozený, byl vyvinut v dalším specializovaném modelovacím jazyce - jazyce Smalltalk (70. léta) a poté byl

Strana 2 z 51

Základní principy OOP

používá se v nových verzích univerzálních programovacích jazyků, jako je Pascal, C++,

Hlavní výhoda OOP- snížení počtu mezimodulových hovorů a snížení množství informací přenášených mezi moduly,

ve srovnání s modulárním programováním. Toho je dosaženo prostřednictvím úplnější lokalizace dat a integrace s rutinami zpracování,

což umožňuje prakticky nezávislý vývoj jednotlivých částí

(objekty) programu.

Objektový přístup navíc nabízí nové nástroje technologického rozvoje, jako je kupř dědičnost, polymorfismus, složení, výplň,

umožňuje vytvářet složité objekty z jednodušších. V důsledku toho se výrazně zvyšuje míra opětovného použití kódu,

Je možné vytvářet knihovny objektů pro různé aplikace a vývojáři dostávají další příležitosti k vytváření systémů se zvýšenou složitostí.

Hlavní nevýhodou OOP je mírný pokles výkonu v důsledku složitější organizace softwarového systému.

OOP je založeno na následujících principech: abstrakce,

omezení přístupu, modularita, hierarchie, psaní, paralelismus,

udržitelnost.

Podívejme se, jaké jsou jednotlivé principy.

A b p s t r a g e- proces identifikace abstrakcí v předmětu úkolu. Abstrakce je soubor základních charakteristik nějakého předmětu, který jej odlišuje od všech ostatních typů předmětů a,

tedy jasně definují znaky daného objektu z hlediska dalšího uvažování a analýzy. V souladu s definicí závisí použitá abstrakce reálného předmětu výrazně na řešeném problému: v jednom případě nás bude zajímat tvar předmětu, v jiném váha, v

třetí - materiály, ze kterých je vyroben, čtvrtý - zákon pohybu

Strana 3 z 51

Základní principy OOP

předmět atd. Moderní úroveň abstrakce zahrnuje sjednocení všech vlastností abstrakce (obě těch, které se týkají stavu analyzovaného objektu,

a určování jeho chování) do jediné programové jednotky určité

abstraktní typ (třída).

Omezení přístupu- skrytí jednotlivých prvků realizace abstrakce, které neovlivňují její podstatné vlastnosti jako celku.

Potřeba omezit přístup vyžaduje v popisu abstrakce rozlišovat mezi dvěma částmi:

rozhraní - soubor prvků implementace abstrakce přístupných zvenčí (hlavní charakteristiky stavu a chování);

implementace - soubor prvků realizace abstrakce, které jsou zvenčí nepřístupné (vnitřní organizace abstrakce a mechanismy pro realizaci jejího chování).

Omezení přístupu v OOP umožňuje vývojáři:

provádět výstavbu systému po etapách, aniž by se rušili implementačními prvky použitých abstrakcí;

je snadné modifikovat implementaci jednotlivých objektů, což ve správně organizovaném systému nebude vyžadovat změny jiných objektů.

Kombinace spojení všech vlastností objektu (složek jeho stavu a chování) do jediné abstrakce a omezení přístupu k implementaci těchto vlastností se nazývá zapouzdření.

MODULARITA- princip vývoje softwarového systému,

návrh jeho realizace formou samostatných částí (modulů). Při rozkladu systému na moduly je žádoucí kombinovat logicky související části a zajistit pokud možno snížení počtu externích spojení mezi moduly. Princip je zděděn z

Strana 4 z 51

Základní principy OOP

modulární programování, jeho dodržování zjednodušuje návrh a

ladění programu.

Hierarchie je seřazený nebo uspořádaný systém abstrakcí.

Princip hierarchie zahrnuje použití hierarchií při vývoji softwarových systémů.

OOP používá dva typy hierarchie.

Hierarchie "celek/část"- označuje, že jsou povoleny některé abstrakce

do předmětné abstrakce jako její části, například lampa se skládá ze základny, žárovky a žárovky. Tato verze hierarchie se používá v procesu dělení systému v různých fázích návrhu (na logické úrovni - při rozkladu předmětné oblasti na objekty, na fyzické úrovni - při rozkladu systému na moduly a při oddělování jednotlivých procesů v víceprocesový systém).

Hierarchie "obecná/soukromá"- ukazuje, že nějaká abstrakce je zvláštním případem jiné abstrakce, například "jídelní stůl -

konkrétní typ stolu“ a „stoly jsou specifickým typem nábytku“. Používá

vývoj struktury tříd, kdy se složité třídy budují na základě jednodušších tak, že se k nim přidávají nové vlastnosti a případně se objasňují ty stávající.

Jedním z nejdůležitějších mechanismů OOP je dědění vlastností ve veřejné/soukromé hierarchii. Dědičnost je vztah mezi abstrakcemi, kdy jedna z nich používá strukturální nebo funkční část jiné nebo několika dalších abstrakcí (jednoduchých a vícenásobných, resp.

dědictví).

TIPZACE - omezení kladené na vlastnosti předmětů a

zamezení zaměnitelnosti abstrakcí různého typu (nebo výrazné snížení možnosti takové záměny). V silně typizovaných jazycích pro každý objekt programu (proměnná, podprogram, parametr atd.)

deklaruje typ, který definuje sadu operací na

Strana 5 z 51

Základní principy OOP

odpovídající softwarový objekt. Programovací jazyky založené na Pascalu diskutované níže používají striktní a ty založené na C -

průměrný stupeň typizace.

Použití principu psaní zajišťuje:

včasná detekce chyb spojených s neplatnými operacemi na programových objektech (chyby jsou detekovány ve fázi kompilace programu při kontrole přípustnosti provedení dané operace na programovém objektu);

zjednodušení dokumentace;

schopnost generovat efektivnější kód.

Typ lze k softwarovému objektu přiřadit staticky (typ objektu je určen v době kompilace - předčasná vazba) a dynamicky (typ objektu je určen pouze během provádění programu - pozdní vazba). Implementace pozdní vazby v programovacím jazyce umožňuje vytvářet proměnné – ukazatele na objekty patřící do různých tříd (polymorfní objekty), což výrazně rozšiřuje možnosti jazyka.

P a r l l e l i s m- vlastnost několika abstrakcí, které jsou současně v aktivním stavu, tzn. provádět nějaké operace.

Existuje řada úkolů, jejichž řešení vyžaduje současné provedení určitých posloupností akcí. Na takové úkoly

například úkoly související s automatickým řízením několika procesů.

Skutečného paralelismu je dosaženo pouze při implementaci úloh tohoto typu na víceprocesorových systémech, kdy je možné provádět každý proces na samostatném procesoru. Jednoprocesorové systémy simulují paralelismus rozdělením času procesoru mezi úkoly řízení různých procesů. V závislosti na typu použitého operačního systému (jedno nebo víceprogramové)

Strana 6 z 51

Základní principy OOP

sdílení času může být provedeno buď vyvíjeným systémem (jako např

MS DOS), nebo použitý OS (jako v systémech Windows).

Stabilita- vlastnost abstrakce existovat v čase bez ohledu na proces, který vygeneroval daný softwarový objekt, a/nebo v prostoru, pohybující se z adresního prostoru, ve kterém byl vytvořen.

Existují:

∙ dočasné objekty, které ukládají mezivýsledky určitých akcí, jako jsou výpočty;

∙ lokální objekty, které existují uvnitř podprogramů, jejichž životnost se počítá od volání podprogramu do jeho dokončení;

∙ globální objekty, které existují během načítání programu do paměti;

∙ uložené objekty, jejichž data jsou mezi relacemi programu uložena v souborech externí paměti.

Všechny výše uvedené principy jsou v té či oné míře implementovány v různých verzích objektově orientovaných jazyků.

Objektově orientované programovací jazyky. Jazyk se počítá objektově orientovaný,pokud implementuje první čtyři ze sedmi diskutovaných zásad.

Zvláštní místo zaujímají objektové modely Delphi a C++Builder. Tyto modely zobecňují zkušenosti s OOP pro MS DOS a zahrnují některé nové funkce,

zajištění efektivního vytváření složitějších systémů. Na základě těchto modelů byla vytvořena vizuální prostředí pro vývoj aplikací Windows.

Složitost programování pod Windows byla výrazně překonána

snížení vytvářením speciálních knihoven objektů, které „skryly“ mnoho prvků programovacích technik.

Strana 7 z 51

Základní principy OOP

Etapy vývoje softwarových systémů pomocí OOP.

Proces vývoje softwaru pomocí OOP zahrnuje čtyři fáze: analýza, návrh, vývoj, modifikace.

Podívejme se na tyto fáze.

Analýza . Účelem analýzy je co nejúplnější popis problému. V této fázi se provede analýza problémové domény, provede se objektová dekompozice vyvíjeného systému a určí se nejdůležitější rysy chování objektů (popis abstrakcí). Na základě výsledků analýzy je vyvinuto blokové schéma softwarového produktu, které ukazuje hlavní objekty a zprávy přenášené mezi nimi a také popisuje abstrakce.

Design. Existují:

logický design, ve kterých jsou učiněná rozhodnutí prakticky nezávislá na provozních podmínkách (operační systém a použité zařízení);

fyzický design, ve kterém je třeba tyto faktory zohlednit.

Logický design je vytvořit strukturu třídy:

jsou definována pole pro ukládání komponent stavu objektů a algoritmy metod, které implementují aspekty chování objektů. V tomto případě se používají techniky vývoje třídy popsané výše (dědičnost,

složení, obsah, polymorfismus atd.). Výsledkem je hierarchie nebo diagram tříd zobrazující vztahy mezi třídami a popis tříd.

Fyzický design zahrnuje kombinování popisů tříd do modulů, výběr jejich schématu připojení (statické nebo dynamické rozložení), určení způsobů interakce se zařízením,

operační systém a/nebo jiný software (např.

databáze, síťové programy), zajištění synchronizace procesů pro paralelní zpracovatelské systémy atd.

Strana 8 z 51

Základní principy OOP

Evoluce systémů. Jedná se o proces implementace krok za krokem a

připojení tříd k projektu. Proces začíná vytvořením základního programu nebo projektu pro budoucí softwarový produkt. Poté jsou třídy implementovány a propojeny tak, aby vytvořily hrubé, ale pokud možno

funkční prototyp budoucího systému. Je otestován a odladěn.

Takovým prototypem může být například systém, který zahrnuje implementaci hlavního rozhraní softwarového produktu (zprávy nejsou přenášeny do části systému, která ještě není dostupná). Díky tomu obdržíme funkční prototyp produktu, který může být například zákazníkovi předveden pro upřesnění požadavků. Poté je k systému připojena další skupina tříd, například spojená s implementací určité položky menu.

Výsledná verze je také testována a laděna a tak dále, dokud nejsou realizovány všechny možnosti systému.

Použití fázované implementace výrazně zjednodušuje testování a ladění softwarového produktu.

Modifikace. Je to proces přidávání nových funkcí nebo změn stávajících vlastností systému. Obvykle,

změny ovlivňují implementaci třídy a ponechávají její rozhraní nezměněné, což se při použití OOP obvykle obejde bez větších problémů, protože proces změny ovlivňuje místní oblast.

Změna rozhraní také není příliš obtížný úkol, ale jeho řešení může vyžadovat koordinaci procesů interakce mezi objekty, což bude vyžadovat změny v jiných třídách programu. Snížení počtu parametrů v rozhraní ve srovnání s modulárním programováním však tento proces značně zjednodušuje.

Jednoduchost úprav umožňuje relativně snadné přizpůsobování softwarových systémů měnícím se provozním podmínkám, což zvyšuje životnost systémů, jejichž vývoj vyžaduje enormní časové a materiálové zdroje.

Strana 9 z 51

Základní principy OOP

Zvláštností OOP je, že objekt nebo skupinu objektů lze vyvíjet samostatně, a proto jejich návrh může být v různých fázích. Například třídy rozhraní již byly implementovány, ale struktura doménových tříd se stále dolaďuje.

Návrh obvykle začíná, když je jakýkoli fragment předmětné oblasti dostatečně plně popsán v procesu analýzy.

Úvahu o základních technikách objektového přístupu začneme dekompozicí objektu.

Dekompozice objektu

Jak bylo uvedeno výše, při použití technologie OOP je řešení znázorněno ve formě výsledek vzájemného působení jednotlivých funkčních prvků nějaký systém, který simuluje procesy,

vyskytující se v předmětné oblasti úkolu.

V takovém systému každý funkční prvek, který obdržel nějaký vstupní vliv (nazývaný zpráva) v procesu řešení problému,

provádí předem určené akce (může například měnit svůj vlastní stav, provádět některé výpočty, kreslit okno nebo graf a naopak ovlivňovat další prvky). Proces řešení problémů je řízen sled zpráv. Předáním těchto zpráv z prvku na prvek systém provede potřebné akce.

Funkční prvky systému, jejichž parametry a chování jsou určeny stavem problému, a mají nezávislé chování

(tj. „schopný“ provádět určité akce v závislosti na přijatých zprávách a stavu prvku) se nazývají objekty.

Nazývá se proces reprezentace problémové domény jako kolekce objektů vyměňujících si zprávy rozklad objektu.

Strana 10 z 51

Základní principy OOP

Abychom pochopili, o jakých objektech a zprávách se diskutuje při provádění dekompozice objektů v každém konkrétním případě, je třeba připomenout, že objektový přístup byl původně navržen pro vývoj simulačních modelů chování komplexních systémů. Soubor objektů takových systémů je obvykle určen analýzou simulovaných procesů.

Příklad. Dekompozice objektů (simulační model

čerpací stanice). Zajímejme se o závislost délky fronty na čerpací stanici na počtu čerpacích stanic, parametrech obsluhy každé čerpací stanice a intenzitě požadavků na tankování (uvažujeme o stejném typu paliva).

Problémy tohoto typu se obvykle řeší pomocí simulačních modelů. Model programově simuluje reálný proces s danými parametry a současně zaznamenává jeho charakteristiky. Mnohonásobným opakováním simulačního procesu s různými hodnotami parametrů služeb nebo příjmu požadavků získá výzkumník konkrétní hodnoty charakteristik, na kterých jsou sestrojeny grafy analyzovaných závislostí.

Proces provozu čerpací stanice se třemi čerpacími stanicemi lze znázornit formou diagramu.

Nevím, jak programovat v objektově orientovaných jazycích. Neučil jsem se. Po 5 letech průmyslového programování v Javě stále nevím, jak vytvořit dobrý systém v objektově orientovaném stylu. prostě nechápu.

Snažil jsem se učit, upřímně. Studoval jsem vzory, četl kód open source projektů, zkoušel jsem si v hlavě budovat ucelené koncepty, ale stále jsem nepochopil principy tvorby kvalitních objektově orientovaných programů. Možná jim rozuměl někdo jiný, ale já ne.

A tady je pár věcí, které mě pletou.

Nevím, co je OOP

Vážně. Je pro mě těžké formulovat hlavní myšlenky OOP. Ve funkcionálním programování je jednou z hlavních myšlenek bezstavová. Ve strukturálním - rozkladu. V modulárním provedení je funkčnost rozdělena do celých bloků. V každém z těchto paradigmat platí dominantní principy pro 95 % kódu a jazyk je navržen tak, aby podporoval jejich používání. Neznám žádná taková pravidla pro OOP.
  • Abstrakce
  • Zapouzdření
  • Dědictví
  • Polymorfismus
Vypadá to jako soubor pravidel, že? To jsou tedy pravidla, která je potřeba dodržovat v 95 % případů? Hmm, pojďme se na to podívat blíže.

Abstrakce

Abstrakce je mocný programovací nástroj. To nám umožňuje budovat velké systémy a udržovat nad nimi kontrolu. Je nepravděpodobné, že bychom se kdy přiblížili dnešní úrovni programů, kdybychom nebyli vyzbrojeni takovým nástrojem. Jak však souvisí abstrakce s OOP?

Za prvé, abstrakce není atributem výhradně OOP nebo programování obecně. Proces vytváření úrovní abstrakce zasahuje téměř do všech oblastí lidského poznání. O materiálech tak můžeme soudit, aniž bychom zacházeli do detailů jejich molekulární struktury. Nebo mluvit o předmětech, aniž byste zmínili materiály, ze kterých jsou vyrobeny. Nebo mluvit o složitých mechanismech, jako je počítač, turbína letadla nebo lidské tělo, aniž bychom si pamatovali jednotlivé detaily těchto entit.

Za druhé, v programování vždy existovaly abstrakce, počínaje spisy Ady Lovelace, která je považována za první programátorku v historii. Od té doby lidé neustále vytvářejí abstrakce ve svých programech, často pouze s těmi nejjednoduššími nástroji. Abelson a Sussman tedy ve své známé knize popisují, jak vytvořit systém pro řešení rovnic, který podporuje komplexní čísla a dokonce i polynomy, pouze pomocí procedur a spojených seznamů. Jaké další prostředky abstrakce tedy OOP poskytuje? Nemám ponětí. Rozdělení kódu do podprogramů? To dokáže jakýkoli jazyk na vysoké úrovni. Kombinovat rutiny na jednom místě? Na to je dostatek modulů. Typizace? Existovalo dávno před OOP. Příklad se systémem pro řešení rovnic jasně ukazuje, že konstrukce úrovní abstrakce nezávisí ani tak na jazykových nástrojích, ale na schopnostech programátora.

Zapouzdření

Hlavní výhodou zapouzdření je skrytí implementace. Klientský kód vidí pouze rozhraní a může se na něj spolehnout. To uvolní vývojářům, kteří se mohou rozhodnout implementaci změnit. A to je opravdu skvělé. Otázkou ale opět je, co s tím má společného OOP? Všechno Výše uvedená paradigmata zahrnují skrytí implementace. Při programování v C alokujete rozhraní do hlavičkových souborů, Oberon vám umožňuje vytvořit pole a metody lokální pro modul a konečně abstrakce v mnoha jazycích je postavena jednoduše pomocí podprogramů, které také zapouzdřují implementaci. Objektově orientované jazyky jsou navíc samy o sobě často porušují pravidlo zapouzdření, poskytování přístupu k datům prostřednictvím speciálních metod - getterů a setterů v Javě, vlastností v C# atp. (V komentářích jsme zjistili, že některé objekty v programovacích jazycích nejsou objekty z pohledu OOP: objekty přenosu dat jsou zodpovědné pouze za přenos dat, a nejsou tedy plnohodnotnými OOP entitami, a proto neexistuje potřebují, aby zachovaly zapouzdření. Na druhou stranu, metody přístupového objektu jsou nejlépe zachovány, aby byla zachována architektonická flexibilita. Takto se to komplikuje.) Navíc některé objektově orientované jazyky, jako je Python, se nesnaží vůbec nic skrývat , ale spolehněte se pouze na inteligenci vývojářů používajících tento kód.

Dědictví

Dědičnost je jednou z mála novinek, které díky OOP skutečně vstoupily na scénu. Ne, objektově orientované jazyky nevytvořily novou myšlenku - dědičnost lze implementovat v jakémkoli jiném paradigmatu - ale OOP poprvé přinesl tento koncept na úroveň jazyka samotného. Výhody dědičnosti jsou také zřejmé: když si téměř spokojeni s nějakou třídou, můžete vytvořit potomka a přepsat nějakou část jeho funkčnosti. V jazycích, které podporují vícenásobnou dědičnost, jako je C++ nebo Scala (v druhém případě prostřednictvím vlastností), se objevuje další případ použití - mixiny, malé třídy, které umožňují „namíchat“ funkce do nové třídy bez kopírování kódu.

Takže to je to, co odlišuje OOP jako paradigma od ostatních? Hmm... pokud ano, proč to tak zřídka používáme ve skutečném kódu? Pamatujete si, co jsem řekl o 95 % kódu, který se řídí pravidly dominantního paradigmatu? Nedělal jsem si srandu. Ve funkčním programování minimálně 95 % kódu využívá neměnná data a funkce bez vedlejších efektů. V modulárním systému je téměř veškerý kód logicky zabalen do modulů. Zastánci strukturovaného programování se podle Dijkstrových předpisů snaží rozdělit všechny části programu na malé části. Dědičnost se používá mnohem méně často. Možná v 10% kódu, možná v 50%, v některých případech (například při dědění z rámcových tříd) - v 70%, ale ne více. Protože ve většině situací je to snadné není třeba.

Navíc dědictví nebezpečný za dobrý design. Tak nebezpečné, že Gang čtyř (zdánlivě kazatelé OOP) ve své knize doporučuje nahradit to delegováním, kdykoli je to možné. Dědičnost tak, jak existuje v aktuálně populárních jazycích, vede ke křehkému designu. Třída, která byla zděděna od jednoho předka, již nemůže být zděděna od ostatních. Nebezpečnou se stává i změna předka. Existují samozřejmě soukromé/chráněné modifikátory, ale také vyžadují značné psychické schopnosti, aby odhadly, jak se třída může změnit a jak ji může klientský kód používat. Dědičnost je tak nebezpečná a nepohodlná, že ji velké frameworky (jako Spring a EJB v Javě) opouštějí ve prospěch jiných, neobjektově orientovaných nástrojů (například metaprogramování). Důsledky jsou tak nepředvídatelné, že některé knihovny (jako je Guava) přiřazují svým třídám modifikátory, které zakazují dědění, a v novém jazyce Go bylo rozhodnuto o úplném opuštění hierarchie dědičnosti.

Polymorfismus

Možná je polymorfismus to nejlepší na objektově orientovaném programování. Díky polymorfismu vypadá při výstupu objekt typu Osoba jako „Shandorkin Adam Impolitovich“ a objekt typu Bod vypadá jako „“. Právě to vám umožňuje napsat „Mat1 * Mat2“ a získat součin matic, podobný součinu běžných čísel. Bez něj by nebylo možné číst data ze vstupního toku, aniž by bylo jedno, zda pocházejí ze sítě, souboru nebo řádku v paměti. Všude tam, kde jsou rozhraní, je také implikován polymorfismus.

Moc se mi líbí polymorfismus. Proto nebudu ani mluvit o jeho problémech v běžných jazycích. O zúženosti expedičního přístupu pouze podle typu a o tom, jak by se to dalo udělat, také pomlčím. Ve většině případů funguje jak má, což není špatné. Otázka zní: je polymorfismus právě tím principem, který odlišuje OOP od jiných paradigmat? Kdybyste se mě zeptali (a protože čtete tento text, můžete předpokládat, že jste se zeptali), odpověděl bych „ne“. A důvodem je stále stejné procento využití v kódu. Možná jsou rozhraní a polymorfní metody trochu častější než dědičnost. Porovnejte ale počet řádků kódu, který zabírají, s počtem řádků napsaných obvyklým procedurálním stylem – těch druhých je vždy více. Při pohledu na jazyky, které podporují tento styl programování, bych je nenazval polymorfními. Jazyky, které podporují polymorfismus – ano, to je normální. Ale ne polymorfní jazyky.

(To je však můj názor. Vždy můžete nesouhlasit.)

Takže abstrakce, zapouzdření, dědičnost a polymorfismus - to vše je v OOP, ale nic z toho není jeho integrálním atributem. Co je tedy OOP? Existuje názor, že podstata objektově orientovaného programování spočívá v objektech (zní to docela logicky) a třídách. Je to myšlenka kombinace kódu a dat a myšlenka, že objekty v programu odrážejí entity v reálném světě. K tomuto názoru se vrátíme později, ale nejprve si řekněme některá já.

Čí OOP je chladnější?

Z předchozí části je zřejmé, že programovací jazyky se mohou značně lišit ve způsobu implementace objektově orientovaného programování. Pokud vezmete souhrn všech implementací OOP ve všech jazycích, pak s největší pravděpodobností nenajdete jedinou vlastnost společnou všem. Abych tuto zoo nějak omezil a upřesnil úvahy, zaměřím se pouze na jednu skupinu – čistě objektově orientované jazyky, a to Java a C#. Termín „čistě objektově orientovaný“ v tomto případě znamená, že jazyk nepodporuje jiná paradigmata nebo je implementuje prostřednictvím stejného OOP. Například Python nebo Ruby nebudou čisté, protože můžete na nich snadno napsat plnohodnotný program bez jediné deklarace třídy.

Abychom lépe pochopili podstatu OOP v Javě a C#, podívejme se na příklady implementace tohoto paradigmatu v jiných jazycích.

Pokec. Na rozdíl od svých moderních protějšků byl tento jazyk dynamicky typován a k implementaci OOP používal styl předávání zpráv. Místo volání metod si objekty posílaly zprávy, a pokud příjemce nedokázal zpracovat to, co přišlo, jednoduše zprávu přeposlal někomu jinému.

Lisp obecný. Zpočátku se CL řídila stejným paradigmatem. Pak se vývojáři rozhodli, že psaní `(odeslat obj "nějaká-zpráva)` je příliš dlouhé, a převedli zápis na volání metody - `(nějaká metoda obj)` Dnes má Common Lisp vyspělý objektově orientovaný programovací systém ( CLOS) s podporou vícenásobné dědičnosti, multimetod a metatříd. Charakteristickým rysem je, že OOP v CL se netočí kolem objektů, ale kolem generických funkcí.

Clojure. Clojure má dva objektově orientované programovací systémy – jeden zděděný z Javy a druhý založený na multimetodách a více podobný CLOS.

R. Tento jazyk pro statistickou analýzu dat má také 2 objektově orientované programovací systémy - S3 a S4. Oba jsou zděděny z jazyka S (což není překvapivé, vzhledem k tomu, že R je open source implementace komerčního S). S4 do značné míry odpovídá implementacím OOP v moderních mainstreamových jazycích. S3 je lehčí varianta, jednoduše implementovaná pomocí samotného jazyka: je vytvořena jedna obecná funkce, která odesílá požadavky na základě atributu „class“ přijatého objektu.

JavaScript. Ideologicky podobný Smalltalku, i když používá jinou syntaxi. Místo dědičnosti používá prototypování: pokud požadovaná vlastnost nebo volaná metoda není v objektu samotném, pak je požadavek předán objektu prototypu (vlastnost prototypu všech objektů JavaScriptu). Zajímavostí je, že chování všech objektů třídy lze změnit nahrazením jedné z prototypových metod (velmi pěkně vypadá například přidání metody `.toBASE64` pro třídu string).

Krajta. Obecně se řídí stejným konceptem jako mainstreamové jazyky, ale také podporuje předávání vyhledávání atributů jinému objektu, jako v JavaScriptu nebo Smalltalku.

Haskell. V Haskellu není vůbec žádný stav, a tudíž žádné předměty v obvyklém smyslu. Stále však existuje určitý druh OOP: datové typy mohou patřit do jedné nebo více typových tříd. Například téměř všechny typy v Haskellu jsou ve třídě Eq (odpovědné za porovnávací operace mezi 2 objekty) a všechna čísla jsou navíc ve třídách Num (operace s čísly) a Ord (operace s čísly).<, <=, >=, >). V menstruačních jazycích typy odpovídají třídám (dat) a typové třídy odpovídají rozhraním.

Státní nebo bez státní příslušnosti?

Vraťme se ale k běžnějším objektově orientovaným programovacím systémům. Co jsem nikdy nedokázal pochopit, je vztah objektů k vnitřnímu stavu. Před studiem OOP bylo vše jednoduché a transparentní: existují struktury, které uchovávají několik souvisejících dat, existují procedury (funkce), které je zpracovávají. venčit (pes), vybrat (účet, částka). Pak předměty dorazily, a to bylo také v pořádku (ačkoli čtení programů bylo mnohem obtížnější - můj pes chodil [kdo?] a účet vybíral peníze [odkud?]). Pak jsem se dozvěděl o skrývání dat. Psa jsem ještě mohl venčit, ale už jsem se nemohl dívat na složení jeho potravy. Jídlo nic neudělalo (asi by se dalo napsat food.eat(pes), ale pořád dávám přednost tomu, aby můj pes jedl jídlo, než naopak). Jídlo jsou jen data a já (a můj pes) jsem k nim potřeboval mít přístup. Všechno Prostě. Ale už se nedalo zapadnout do rámce paradigmatu, jako do starých džínů z konce 90. let.

Dobře, máme metody přístupu k datům. Dopřejme si tento malý sebeklam a předstírejme, že naše data jsou skutečně skryta. Ale teď už vím, že objekty jsou především data a pak možná metody, které je zpracovávají. Pochopil jsem, jak psát programy, o co se při navrhování snažit.

Než jsem si stačil užít osvícení, uviděl jsem na internetu slovo bez státní příslušnosti (přísahal bych, že ho obklopovala zář a nad písmeny t a l viselo svatozář). Krátké studium literatury odhalilo úžasný svět transparentního toku řízení a jednoduchého multithreadingu bez nutnosti sledovat konzistenci objektů. Samozřejmě jsem se okamžitě chtěl dotknout tohoto nádherného světa. To však znamenalo naprosté odmítnutí jakýchkoli pravidel – nyní nebylo jasné, zda má pes chodit sám, nebo je k tomu potřeba speciální Walk Manager; potřebujete účet, nebo veškerou práci zařídí banka, a pokud ano, měla by odepisovat peníze staticky nebo dynamicky atd. Počet případů užití se exponenciálně zvýšil a všechny budoucí případy užití by mohly vést k potřebě velkého refaktoringu.

Stále nevím, kdy by měl být objekt bezstavový, kdy by měl být stavový a kdy by to měl být pouze datový kontejner. Někdy je to zřejmé, ale většinou ne.

Psaní: statické nebo dynamické?

Další věc, kterou se u jazyků jako C# a Java nemohu rozhodnout, je, zda jsou staticky nebo dynamicky typovány. Většina lidí pravděpodobně zvolá: „Jaký nesmysl! Samozřejmě staticky typováno! Typy jsou kontrolovány v době kompilace! Ale je to opravdu tak jednoduché? Je pravda, že zadáním typu X v parametrech metody si programátor může být jistý, že mu budou vždy předány objekty typu X? To je pravda - nemůže, protože... bude možné předat parametr typu X metodě X nebo jeho dědice. Zdálo by se, no a co? Potomci třídy X budou mít stále stejné metody jako X. Metody jsou metody, ale logika práce se může ukázat jako úplně jiná. Nejčastějším případem je situace, kdy se ukáže, že podřízená třída je optimalizována pro jiné potřeby než X a naše metoda může počítat přesně s touto optimalizací (pokud se vám takový scénář zdá nereálný, zkuste napsat plugin pro nějakou vyvinutou open source knihovnu - nebo strávíte několik týdnů analýzou architektury a algoritmů knihovny, nebo jednoduše náhodně zavoláte metody s vhodnou signaturou). Ve výsledku program funguje, ale rychlost provozu řádově klesne. I když z pohledu překladače je vše správně. Je příznačné, že Scala, která je nazývána nástupcem Javy, na mnoha místech standardně umožňuje předávat pouze argumenty zadaného typu, i když toto chování lze změnit.

Dalším problémem je hodnota null, kterou lze předat místo téměř jakéhokoli objektu v Javě a místo jakéhokoli objektu s možností Null v C#. null patří do všech typů najednou a zároveň nepatří k žádnému. null nemá ani pole ani metody, takže jakékoli jeho volání (kromě kontroly null) má za následek chybu. Zdá se, že na to jsou všichni zvyklí, ale pro srovnání je Haskell (a stejná Scala) nucen používat speciální typy (Možná v Haskellu, Option ve Scale) k zabalení funkcí, které by v jiných jazycích mohly vrátit hodnotu null. V důsledku toho o Haskell často říkají „je obtížné na něm zkompilovat program, ale pokud uspějete, pak s největší pravděpodobností funguje správně“.

Na druhou stranu mainstreamové jazyky zjevně nejsou dynamicky typovány, a proto nemají takové vlastnosti jako jednoduchá rozhraní a flexibilní postupy. V důsledku toho je také nemožné psát ve stylu Python nebo Lisp.

Jaký je rozdíl v tom, co se nazývá toto psaní, pokud jsou všechna pravidla stejně známá? Rozdíl je v tom, z jaké strany k návrhu architektury přistupujete. Existuje dlouhodobá debata o tom, jak postavit systém: vytvořit mnoho typů a málo funkcí, nebo málo typů a mnoho funkcí? První přístup je aktivně používán v Haskell, druhý v Lisp. Moderní objektově orientované jazyky používají něco mezi tím. Nechci říkat, že je to špatně - asi to má své výhody (ostatně bychom neměli zapomínat, že Java a C# jsou vícejazyčné platformy), ale pokaždé, když zakládám nový projekt, přemýšlím, kde začít navrhování - s typy nebo z funkčnosti.

A dál...

Nevím, jak modelovat problém. Předpokládá se, že OOP umožňuje zobrazit objekty reálného světa v programu. Nicméně ve skutečnosti mám psa (se dvěma ušima, čtyřmi tlapkami a obojkem) a bankovní účet (s manažerem, úředníky a přestávkou na oběd) a v programu - WalkManager, AccountFactory... no, dostanete idea. A nejde o to, že program má pomocné třídy, které neodrážejí objekty reálného světa. Faktem je, že kontrolovat změny toku. Walking Manager mě okrádá o radost z venčení mého psa a já dostávám peníze z bezduchého bankovního účtu (hej, kde je ta roztomilá holka, u které jsem minulý týden změnil peníze?).

Možná jsem snob, ale mnohem šťastnější jsem byl, když data v počítači byla jen data, i když popisovala mého psa nebo bankovní účet. Mohl jsem s daty dělat, co bylo vhodné, bez ohledu na skutečný svět.

Taky nevím, jak správně rozložit funkčnost. Pokud jsem v Pythonu nebo C++ potřeboval malou funkci pro převod řetězce na číslo, napsal jsem ji na konec souboru. V Javě nebo C# jsem nucen to dát do samostatné třídy StringUtils. V pre-OO jazycích bych mohl deklarovat ad hoc obal, který vrátí dvě hodnoty z funkce (vybranou částku a zůstatek na účtu). V OOP jazycích budu muset vytvořit plnohodnotnou třídu Transaction Result. A novému člověku na projektu (nebo i mně o týden později) bude tato třída připadat stejně důležitá a zásadní v architektuře systému. 150 souborů a všechny stejně důležité a základní – ach ano, transparentní architektura, úžasné úrovně abstrakce.

Nevím, jak psát efektivní programy. Efektivní programy využívají málo paměti – jinak bude garbage collector neustále zpomalovat provádění. Ale abyste provedli tu nejjednodušší operaci v objektově orientovaných jazycích, musíte vytvořit tucet objektů. Abych vytvořil jeden HTTP požadavek, musím vytvořit objekt typu URL, pak objekt typu HttpConnection, pak objekt typu Request... no, chápete. V procedurálním programování bych jednoduše zavolal několik procedur a předal jim strukturu vytvořenou na zásobníku. S největší pravděpodobností by se v paměti vytvořil pouze jeden objekt – pro uložení výsledku. V OOP musím neustále zahlcovat paměť.

Možná je OOP opravdu krásné a elegantní paradigma. Možná jen nejsem dost chytrý, abych to pochopil. Pravděpodobně existuje někdo, kdo dokáže vytvořit opravdu pěkný program v objektově orientovaném jazyce. No, můžu jim jen závidět.

Pro mnoho programátorů PHP je objektově orientované programování zastrašujícím konceptem, který je plný složité syntaxe a dalších překážek při zvládnutí. V tomto článku koncept objektově orientované programování(OOP) je reprezentován jako styl kódování, který vám umožňuje seskupit související aktivity do tříd a vytvořit tak kompaktnější a efektivnější kód.

Co je objektově orientované programování

Objektově orientované programování je styl kódování, který umožňuje vývojáři seskupit podobné úkoly třídy. Kód tedy vyhovuje principu DRY (neopakujte se) a snadno se udržuje.

Jednou z výhod DRY programování je, že pokud některé informace vyžadují změnu programu, musíte to udělat změňte kód pouze na jednom místě, abyste aktualizovali algoritmus. Jednou z nejhorších nočních můr vývojářů je udržování kódu, který znovu a znovu deklaruje data, čímž se jakékoli změny v programu stávají nekonečnou hrou na schovávanou a zároveň pátrá po duplicitních datech a částech algoritmu.

OOP děsí mnoho vývojářů, protože zavádí novou syntaxi a na první pohled se zdá složitější než jednoduché procedurální kódování. Při bližším zkoumání je však OOP ve skutečnosti velmi jasný a extrémně jednoduchý přístup k programování.

Co jsou objekty a třídy

Než se ponoříme do jasných definic OOP, je nutné mít základní pochopení rozdílu mezi třídy A objektů. Tato část článku vám pomůže získat představu o třídách, jejich různých schopnostech a některých aplikacích.

Jaký je rozdíl mezi třídami a objekty

Vývojáři, kteří začínají mluvit o třídách a objektech, začínají nahrazovat koncepty. Bohužel se to stává velmi často.

Třída, například, je Projekt domu. Na papíře definuje, jak bude dům vypadat, jasně popisuje všechny vztahy mezi jeho jednotlivými částmi, i když dům ve skutečnosti neexistuje.

A objekt je skutečný dům, která je postavena v souladu s projektem. Data, která jsou uložena v objektu, jsou jako dřevo, dráty a beton, které tvoří dům: bez montáže podle návrhu to bude jen hromada materiálů. Když se však spojí dohromady, tvoří vynikající a pohodlný domov.

Třídy tvoří strukturu dat a akcí a využívají tyto informace ke konstrukci objektů. Z jedné třídy lze sestavit více objektů současně, každý z nich bude nezávislý na ostatních. Pokračujeme-li v analogii se stavebnictvím, celá čtvrť by mohla být postavena podle jednoho návrhu: 150 různých domů, které vypadají stejně, ale v každém z nich sídlí jiné rodiny a vnitřní výzdoba budov je odlišná.

Struktura třídy

Syntaxe pro vytvoření třídy je velmi jednoduchá: k deklaraci třídy použijte klíčové slovo class, za nímž následuje název třídy a sada složených závorek (()):

Po vytvoření třídy lze vytvořit instanci nového objektu a uložit jej do proměnné pomocí klíčového slova new:

$obj = new MyClass;

Chcete-li zobrazit obsah objektu, použijte var_dump() :

Var_dump($obj);

Celý proces můžete otestovat zkopírováním celého kódu do souboru test.php:

Načtěte stránku do prohlížeče a na obrazovce by se měl objevit následující řádek:

Object(MyClass)#1 (0) ( )

Právě jste vytvořili svůj první OOP skript.

Definování vlastností třídy

Vlastnosti nebo proměnné třídy se používají k přidávání dat do třídy. Vlastnosti fungují jako běžné proměnné, ale jsou přidruženy k objektu a lze k nim přistupovat pouze pomocí objektu.

Chcete-li přidat vlastnosti do třídy MyClass, použijte ve skriptu tento kód:

Klíčové slovo public určuje viditelnost vlastnosti, které se budeme věnovat později v této kapitole. Vlastnost je poté pojmenována pomocí normální syntaxe proměnné a přiřazena hodnota (ačkoli vlastnost třídy nemusí být inicializována).

Echo $obj->prop1;

Protože může existovat více implementací třídy bez odkazu na konkrétní objekt, vlastnost nelze číst, protože skript nemůže určit, ze kterého objektu se má číst. Šipka (->) je OOP konstrukt, který se používá pro přístup k vlastnostem a metodám daného objektu.

Upravte skript v test.php tak, aby četl hodnotu vlastnosti a nezobrazoval informace o celé třídě:

prop1; // Zobrazit vlastnost?>

Obnovte stránku v prohlížeči, abyste viděli výsledek skriptu:

Vlastnost třídy

Definování třídních metod

Metoda je třídní funkce. Jednotlivá akce, kterou může objekt provést, je definována ve třídě jako metoda.

Vytvořme například metody, které nastavují a čtou hodnotu vlastnosti $prop1:

prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "
"; ) ) $obj = new MyClass; echo $obj->prop1; ?>

Poznámka- OOP umožňuje objektu odkazovat na sebe pomocí $this . Při práci uvnitř metody vám pomocí $this umožňuje použít název objektu mimo třídu.

Chcete-li použít metodu, zavolejte ji jako běžnou funkci, ale nejprve určete objekt, ke kterému patří. Načteme vlastnost z MyClass , změníme hodnotu a přečteme ji znovu:

prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "
"; ) ) $obj = new MyClass; echo $obj->getProperty(); // získání hodnoty vlastnosti $obj->setProperty("New property."); // Nastavení nové hodnoty echo $obj->getProperty () ; // Přečtěte si hodnotu znovu, abyste viděli změny?>

Obnovíme stránku v prohlížeči a uvidíme následující:

Vlastnost třídy Nová vlastnost

Výhody OOP se projeví při použití více objektů stejné třídy.

prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "
"; ) ) // Vytvořte dva objekty $obj = new MyClass; $obj2 = new MyClass; // Získejte hodnoty $prop1 z obou objektů echo $obj->getProperty(); echo $obj2->getProperty( ); // Nastavení nových hodnot vlastností pro oba objekty $obj->setProperty("Nová hodnota vlastnosti"); $obj2->setProperty("Vlastnost patří druhému objektu"); // Tisk hodnot $prop1 ​​pro oba echo $obj->getProperty() ; echo $obj2->getProperty(); ?>

Když načtete stránku do prohlížeče, uvidíte následující:

Vlastnost třídy Vlastnost třídy Nová hodnota vlastnosti Vlastnost patří druhému objektu

Poznámka, OOP ukládá objekty jako různé entity, což usnadňuje oddělení kódu na různé malé a vzájemně propojené části.

Magické metody v OOP

Aby bylo používání objektů snazší, má PHP několik magické metody. Jedná se o speciální metody, které se volají při provádění určitých akcí s objektem. Tímto způsobem může vývojář relativně snadno dokončit několik běžných úkolů.

Použití konstruktorů a destruktorů

Když je objekt vytvořen, je často nutné, aby byly okamžitě nastaveny určité vlastnosti. K provádění takových úkolů má PHP magickou metodu __construct(), která je volána automaticky, když je vytvořen nový objekt.

Pro ilustraci konceptu přidáme konstruktor do třídy MyClass. Při vytvoření nového objektu třídy vytiskne zprávu:

"; ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "
"; ) ) // Vytvořte nový objekt $obj = new MyClass; // Získejte hodnotu vlastnosti $prop1 echo $obj->
"; ?>

Poznámka— konstanta __CLASS__ vrací název třídy, ve které je volána; toto je jedna z magických konstant PHP.

Objekt třídy "MyClass" byl vytvořen! Konec vlastnosti třídy souboru.

Chcete-li volat funkci během procesu mazání objektu, použijte magickou metodu __destruct(). Toto je velmi užitečná metoda pro správné vymazání vlastností třídy (například pro správné ukončení připojení k databázi).

Při odstranění objektu třídy pomocí magické metody zobrazíme zprávu:
__destruct() v MyClass:

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "
"; ) ) // Vytvořte nový objekt $obj = new MyClass; // Získejte hodnotu vlastnosti $prop1 echo $obj->getProperty(); // Zobrazí zprávu o dosažení konce souboru echo "End souboru.
"; ?>

Obnovíme stránku v prohlížeči a získáme výsledek:

Objekt třídy "MyClass" byl vytvořen! Konec vlastnosti třídy souboru. Objekt třídy "MyClass" byl odstraněn.

Když je dosaženo konce souboru, PHP automaticky uvolní všechny prostředky.

Chcete-li explicitně zavolat destruktor a odstranit objekt, můžete použít funkci unset():


"; ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "
"; ) ) // Vytvořte nový objekt $obj = new MyClass; // Získejte hodnotu vlastnosti $prop1 echo $obj->getProperty(); // Smažte objekt unset($obj); // Zobrazení zpráva o dosažení konce souboru echo "Konec souboru.
"; ?>

Nyní bude výsledek kódu po načtení do prohlížeče vypadat takto:

Objekt třídy "MyClass" byl vytvořen! Vlastnost třídy Objekt třídy "MyClass" byl odstraněn. Konec souboru.

Převést na řetězec

Aby se předešlo chybě, pokud se skript pokusí vydat MyClass jako řetězec, použije se jiná magická metoda, __toString() .

Bez použití __toString() pokus o výstup objektu jako řetězec bude mít za následek závažnou chybu. Zkuste použít funkci echo pro výstup objektu bez použití magické metody:

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty() ( return $this->prop1 . "

"; ?>

Výsledek bude vypadat takto:

Objekt třídy "MyClass" byl vytvořen! Chytitelná závažná chyba: Objekt třídy MyClass nelze převést na řetězec v /Applications/XAMPP/xamppfiles/htdocs/testing/test.php na řádku 40

Chcete-li se vyhnout chybě, použijte metodu __toString():

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty( ) ( return $this->prop1 . "
"; ) ) // Vytvořte nový objekt $obj = new MyClass; // Výstup objektu jako řetězec echo $obj; // Smazání objektu unset($obj); // Výstup zprávy o dosažení konce echo souboru "Konec souboru.
"; ?>

V tomto případě bude mít pokus o převod objektu na řetězec za následek volání metody getProperty(). Načtěte skript do prohlížeče a podívejte se na výsledek:

Objekt třídy "MyClass" byl vytvořen! Používáme metodu toString: Vlastnost třídy Objekt třídy "MyClass" byl odstraněn. Konec souboru.

Použití třídní dědičnosti

Třídy mohou dědit metody a vlastnosti z jiných tříd pomocí klíčového slova extends. Vytvořme například druhou třídu, která rozšíří MyClass a přidá metodu:

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty( ) ( return $this->prop1 . "
"; ) ) třída MyOtherClass rozšiřuje MyClass ( veřejná funkce newMethod() ( echo "Z nové metody třídy " . __CLASS__ .".
"; ) ) // Vytvořte nový objekt $newobj = new MyOtherClass; // Použijte novou metodu echo $newobj->newMethod(); // Použijte metodu z nadřazené třídy echo $newobj->getProperty(); ? >

Po načtení skriptu do prohlížeče dostaneme výsledek:

Objekt třídy "MyClass" byl vytvořen! Z nové metody třídy "MyOtherClass". Vlastnost třídy Objekt třídy "MyClass" byl odstraněn.

Přetěžování zděděných vlastností a metod

Chcete-li změnit chování existujících vlastností nebo metod v nové třídě, můžete je jednoduše přetížit tím, že je znovu deklarujete v nové třídě:

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty( ) ( return $this->prop1 . "
"; ) ) třída MyOtherClass rozšiřuje MyClass ( veřejná funkce __construct() ( echo "Nový konstruktor ve třídě " . __CLASS__ .".

"; ) ) // Vytvořte nový objekt $newobj = new MyOtherClass; // Výstup objektu jako řetězec echo $newobj->newMethod(); // Použijte metodu z nadřazené třídy echo $newobj->getProperty() ;?>

Změny při spuštění kódu vytvoří následující výstup:

Nový konstruktor ve třídě "MyOtherClass". Z nové metody třídy "MyOtherClass". Vlastnost třídy Objekt třídy "MyClass" byl odstraněn.

Zachování původní funkčnosti při přetěžování metod

Chcete-li do zděděné metody přidat novou funkcionalitu při zachování funkčnosti původní metody, použijte nadřazené klíčové slovo with operátor rozlišení viditelnosti ( :: ) :

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) veřejná funkce getProperty( ) ( return $this->prop1 . "
"; ) ) třída MyOtherClass rozšiřuje MyClass ( veřejná funkce __construct() ( parent::__construct(); // Volání konstruktoru nadřazené třídy echo "Nový konstruktor ve třídě " . __CLASS__ .".
";) public function newMethod() ( echo "Z nové metody třídy " . __CLASS__ . ".
"; ) ) // Vytvořte nový objekt $newobj = new MyOtherClass; // Výstup objektu jako řetězec echo $newobj->newMethod(); // Použijte metodu z nadřazené třídy echo $newobj->getProperty() ;?>

Výše uvedený kód po spuštění zobrazí zprávy od konstruktorů nové i nadřazené třídy:

Objekt třídy "MyClass" byl vytvořen! Nový konstruktor ve třídě "MyOtherClass". Z nové metody třídy "MyOtherClass". Vlastnost třídy Objekt třídy "MyClass" byl odstraněn.

Vymezení rozsahu vlastností a metod

Pro další kontrolu nad objekty, metodami a vlastnostmi je nastaven rozsah. To řídí, jak a odkud lze přistupovat k vlastnostem a metodám. Existují tři klíčová slova pro nastavení rozsahu: public , protected a private . Kromě nastavení rozsahu lze metody a vlastnosti deklarovat jako statické, což umožňuje jejich přístup bez implementace třídy.

Poznámka- Rozsah je nová vlastnost, která byla představena v PHP 5. Kompatibilitu OOP s PHP 4 viz manuál PHP.

Vlastnosti a metody veřejné (Obecné)

Všechny vlastnosti a metody, které jste použili dříve v tomto článku, byly veřejné. To znamená, že mohou být přístupné odkudkoli, uvnitř i mimo třídu.

Chráněné metody a vlastnosti

Když je vlastnost nebo metoda deklarována pomocí chráněné směrnice, lze k němu přistupovat pouze v rámci samotné třídy nebo v rámci odvozených tříd(třídy, které rozšiřují základní třídu obsahující metodu s direktivou chráněný).

Pojďme deklarovat metodu getProperty() jako chráněný v MyClass a pokuste se k němu přistupovat mimo třídu:

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) chráněná funkce getProperty( ) ( return $this->prop1 . "

";) public function newMethod() ( echo "Z nové metody třídy " . __CLASS__ . ".
"; ) ) // Vytvořte nový objekt $newobj = new MyOtherClass; // Zkuste zavolat chráněnou metodu echo $newobj->getProperty(); ?>

Při pokusu o spuštění skriptu se vygeneruje následující chyba:

Objekt třídy "MyClass" byl vytvořen! Nový konstruktor ve třídě "MyOtherClass". Závažná chyba: Volání chráněné metody MyClass::getProperty() z kontextu "" v /Applications/XAMPP/xamppfiles/htdocs/testing/test.php na řádku 55

Nyní vytvoříme novou metodu v MyOtherClass pro volání metody getProperty():

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) chráněná funkce getProperty( ) ( return $this->prop1 . "
"; ) ) třída MyOtherClass rozšiřuje MyClass ( veřejná funkce __construct() ( parent::__construct(); echo "Nový konstruktor ve třídě " . __CLASS__ .".
";) public function newMethod() ( echo "Z nové metody třídy " . __CLASS__ . ".
"; ) veřejná funkce callProtected() ( return $this->getProperty(); ) ) // Vytvoření nového objektu $newobj = new MyOtherClass; // Volání chráněné metody z veřejné metody echo $newobj->callProtected() ;?>

Při spuštění skriptu bude výsledek vypadat takto:

Objekt třídy "MyClass" byl vytvořen! Nový konstruktor ve třídě "MyOtherClass". Vlastnost třídy Objekt třídy "MyClass" byl odstraněn.

Metody a vlastnosti soukromé

Vlastnosti a metody deklarované jako soukromé jsou přístupné pouze v rámci třídy, ve které jsou definovány. Znamená to, že i když je nová třída odvozena od třídy, která definuje soukromé vlastnosti a metody, nebudou dostupné v odvozené třídě.

Pro demonstraci deklarujme metodu getProperty() jako soukromé PROTI Moje třída a zkusme zavolat metodu callProtected() from
MyOtherClass :

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) soukromá funkce getProperty( ) ( return $this->prop1 . "
"; ) ) třída MyOtherClass rozšiřuje MyClass ( veřejná funkce __construct() ( parent::__construct(); echo "Nový konstruktor ve třídě " . __CLASS__ .".
";) public function newMethod() ( echo "Z nové metody třídy " . __CLASS__ . ".
"; ) veřejná funkce callProtected() ( return $this->getProperty(); ) ) // Vytvořte nový objekt $newobj = new MyOtherClass; // Použijte metodu z nadřazené třídy echo $newobj->callProtected(); ?>

Uložíme skript, obnovíme stránku v prohlížeči a získáme následující:

Objekt třídy "MyClass" byl vytvořen! Nový konstruktor ve třídě "MyOtherClass". Závažná chyba: Volání soukromé metody MyClass::getProperty() z kontextu "MyOtherClass" v /Applications/XAMPP/xamppfiles/htdocs/testing/test.php na řádku 49

Statické metody a vlastnosti (statické)

K metodám a vlastnostem deklarovaným statickou direktivou lze přistupovat bez iniciace třídy. Jednoduše použijete název třídy, operátor oprávnění viditelnosti a název vlastnosti nebo metody.

Jednou z hlavních výhod statických vlastností je, že si zachovávají své hodnoty v celém skriptu.

Pro demonstraci přidáme do třídy statickou vlastnost $count a statickou metodu plusOne(). Moje třída. Poté nastavíme smyčku do...while, která vytiskne zvyšující se hodnotu $count, dokud nebude větší než 10:

"; ) veřejná funkce __destruct() ( echo "Objekt třídy "", __CLASS__, "" smazáno.
"; ) veřejná funkce __toString() ( echo "Použijte metodu toString: "; return $this->getProperty(); ) veřejná funkce setProperty($newval) ( $this->prop1 = $newval; ) soukromá funkce getProperty( ) ( return $this->prop1 . "
"; ) veřejná statická funkce plusOne() ( return "count = " . ++self::$count . ".
"; ) ) třída MyOtherClass rozšiřuje MyClass ( veřejná funkce __construct() ( parent::__construct(); echo "Nový konstruktor ve třídě " . __CLASS__ .".
";) public function newMethod() ( echo "Z nové metody třídy " . __CLASS__ . ".
"; ) veřejná funkce callProtected() ( return $this->getProperty(); ) ) do ( // Volání plusOne bez iniciace třídy MyClass echo MyClass::plusOne(); ) while (MyClass::$count< 10); ?>

Poznámka- Pro přístup ke statickým vlastnostem musí být znak dolaru ($). přijít po operátorovi povolení viditelnosti.

Spuštěním skriptu v prohlížeči vznikne následující výsledek:

Počet = 1. počet = 2. počet = 3. počet = 4. počet = 5. počet = 6. počet = 7. počet = 8. počet = 9. počet = 10.

obecná informace

OOP je programovací styl, který se objevil v 80. letech 20. století. Na rozdíl od procedurálních jazyků, kde data a instrukce pro jejich zpracování existují odděleně, jsou v objektově orientovaném programování tyto informace sloučeny do jediné entity.

Základní principy OOP

Dědictví

Druhý princip OOP, dědičnost, je schopnost jedné třídy používat metody jiné, aniž by se opakovala jejich skutečná implementace. Dědičnost umožňuje zbavit se redundance ve zdrojovém kódu.

Polymorfismus

Dalším principem OOP je polymorfismus. Jeho použití znamená, že pro manipulaci s objekty různého stupně složitosti můžete vytvořit jedno rozhraní, které bude na události reagovat odlišně a zároveň správně implementovat zadané úkoly.

OOP jazyky

Principy OOP jsou využívány v nejpopulárnějších programovacích jazycích jako C++ a Java, ve kterých je vyvíjena významná část programů a aplikací. Existují také méně používané OOP jazyky - Delphi, Object Pascal, Ruby a mnoho dalších.

Kritika OOP

Navzdory převážně pozitivním vyjádřením k této metodice jsou principy OOP často kritizovány. Stejně jako OOP má své nevýhody.

Za prvé, obtížnost přechodu. Pochopení principů OOP zabere poměrně hodně času, zvláště lidem, kteří úzce spolupracují pouze s procedurálními programovacími jazyky.

Za druhé, nevýhodou je složitější dokumentace, protože bude nutné nejen popisovat třídy a objekty, ale i konkrétní případy jejich implementace.

Za třetí, přílišná univerzálnost metod může vést k tomu, že zdrojový kód a vyvíjené programy budou přetíženy funkcemi a schopnostmi, které nejsou v tomto konkrétním případě žádané. Kromě toho si všímají neefektivity z hlediska alokace paměti. Bez ohledu na názory ostatních však počet OOP programátorů neustále roste a jazyky samotné se rychle rozvíjejí.



Související články: