Třída (programování)

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 18. června 2015; kontroly vyžadují 43 úprav .

Třída  - v objektově orientovaném programování , model pro vytváření objektů určitého typu , popisující jejich strukturu (množinu polí a jejich počáteční stav) a definování algoritmů (funkcí nebo metod ) pro práci s těmito objekty.

Jinými slovy, třída slouží jako prostředek pro zavádění abstraktních datových typů do softwarového projektu. Jiné deskriptory abstraktních datových typů - metatřídy , rozhraní , struktury , výčty - se vyznačují některými svými vlastními charakteristikami. Podstata rozdílu mezi třídami je v tom, že při specifikaci datového typu třída současně definuje rozhraní i implementaci pro všechny své instance (tedy objekty), takže volání metody konstruktoru je povinné.

Třída je jedním z klíčových konceptů v OOP , ale existují i ​​beztřídní objektově orientované jazyky, jako je Self , JavaScript , Lua , (více podrobností viz Prototype Programming ).

V praxi objektově orientované programování spočívá ve vytvoření řady tříd, včetně rozhraní a implementace, a jejich následném použití. Grafické znázornění řady tříd a vztahů mezi nimi se nazývá diagram tříd . Objektově orientovaný přístup během svého vývoje nashromáždil mnoho doporučení ( vzorů ) pro vytváření tříd a hierarchií tříd .

Myšlenka tříd vzešla z práce na znalostní bázi relevantní pro výzkum umělé inteligence. Klasifikace používané člověkem v zoologii, botanice, chemii, strojní součásti nesou základní myšlenku, že jakoukoli věc lze vždy reprezentovat jako speciální případ nějakého obecnějšího pojmu. Konkrétní jablko je jablko obecně, jablko obecně a jakékoli jablko obecně je ovoce. (Jablka a hrušky jsou běžným příkladem tříd v kurzech objektově orientovaného programování.)

Všude níže budou slova "třída", " objekt ", " rozhraní " a " struktura " používána ve zvláštních významech uvedených v OOP.

Třídy a objekty, koncept instance třídy, koncept členů třídy

V objektově orientovaném programu používajícím třídy je každý objekt " instancí " nějaké konkrétní třídy a nejsou poskytovány žádné další objekty. To znamená, že " instance třídy " v tomto případě neznamená "příklad nějaké třídy" nebo "jediná třída", ale "objekt, jehož typem je nějaká třída." Zároveň je v různých programovacích jazycích povolena či zakázána existence některých dalších datových typů, jejichž instance nejsou objekty (to znamená, že jazyk určuje, zda takové věci jako čísla, pole a ukazatele jsou objekty, popř. ne, a podle toho, zda existují třídy jako „číslo“, „pole“ nebo „ukazatel“, jejichž instancí by bylo každé konkrétní číslo, pole nebo ukazatel).

Například abstraktní datový typ „řádek textu“ lze navrhnout jako třídu a všechny řádky textu v programu pak budou objekty – instance třídy „řádek textu“.

Při použití tříd mohou všechny prvky programového kódu, jako jsou proměnné, konstanty, metody, procedury a funkce, patřit (a v mnoha jazycích musí patřit) do jedné nebo druhé třídy. Samotná třída je nakonec definována jako seznam jejích členů , jmenovitě polí ( vlastností ) a metod/funkcí/postupů . V závislosti na programovacím jazyce mohou být do tohoto seznamu přidány konstanty, atributy a externí definice.

Stejně jako struktury mohou třídy definovat pole – tedy proměnné, které patří buď přímo samotné třídě (statické), nebo instancím třídy (obyčejné). Statická pole existují v jedné instanci pro celý program (nebo ve složitější verzi v jedné instanci na proces nebo na vlákno / vlákno ). Obyčejná pole jsou vytvořena jedna kopie pro každý konkrétní objekt - instanci třídy. Například celkový počet řádků textu vytvořených v programu během jeho činnosti bude statickým polem třídy "řádek textu". A konkrétní pole znaků řetězce bude regulárním polem instance třídy „řetězec textu“, stejně jako proměnná „příjmení“ typu „řetězec textu“ bude regulérním polem každé konkrétní instance. třídy "osoba".

V OOP, při použití tříd, budou všechny spustitelné programové kódy (algoritmy) prezentovány ve formě takzvaných "metod", "funkcí" nebo "postupů", což odpovídá konvenčnímu strukturovanému programování , ale nyní mohou (a v mnoho jazyků musí patřit do jedné nebo jiné třídy. Například třída „řetězec textu“ bude pokud možno obsahovat všechny základní metody/funkce/postupy určené pro práci s textovým řetězcem, jako je vyhledávání v řetězci, vyříznutí části řetězce atd.

Stejně jako pole může být kód ve formě metod/funkcí/procedur patřících do třídy odkazován buď na samotnou třídu, nebo na instance třídy. Metoda patřící do třídy a přidružená ke třídě (statická metoda) může být volána sama o sobě a má přístup ke statickým proměnným třídy. Metoda spojená s instancí třídy (běžná metoda) může být volána pouze na samotném objektu a má přístup jak ke statickým polím třídy, tak k běžným polím konkrétního objektu (při volání bude tento objekt předán jako parametr skryté metody). Například celkový počet vytvořených řetězců lze zjistit odkudkoli v programu, ale délku konkrétního řetězce lze zjistit pouze tak, že uvedeme, tím či oním způsobem, délku kterého řetězce budeme měřit.

Rozhraní a implementace, dědičnost implementace

V programování existuje koncept programovacího rozhraní, což znamená seznam možných výpočtů, které může ta či ona část programu provádět. To zahrnuje popis: jaké argumenty a v jakém pořadí je třeba předat na vstup algoritmů ze seznamu a také co a v jaké formě vrátí. Pro formalizovaný popis takového seznamu bylo vynalezeno rozhraní abstraktního datového typu . Samotné algoritmy, tedy skutečný programový kód, který bude provádět všechny tyto výpočty, nejsou specifikovány rozhraním, jsou naprogramovány samostatně a nazývají se implementace rozhraní .

Programovací rozhraní, stejně jako třídy, lze rozšířit pomocí dědičnosti , což je jeden z důležitých prostředků opětovného použití kódu v OOP. Zděděná třída nebo rozhraní bude obsahovat vše, co je specifikováno pro všechny její rodičovské třídy (v závislosti na programovacím jazyce a platformě může být od nuly do nekonečna). Můžete si například vytvořit vlastní verzi textového řetězce zděděním třídy „můj textový řetězec“ z již existující třídy „textový řetězec“, přičemž se předpokládá, že programátor nebude muset přepisovat vyhledávací algoritmy a podobně, protože budou automaticky zděděny z hotové třídy a libovolnou instanci třídy „můj řádek textu“ lze předat nejen hotovým metodám nadřazené třídy „řádek textu“ k provedení nezbytných výpočtů, ale obecné pro jakýkoli algoritmus, který může pracovat s objekty typu „řádek textu“, protože instance rozhraní obou tříd jsou kompatibilní.

Třída umožňuje nastavit nejen programovací rozhraní sobě a jeho instancím, ale také explicitně napsat kód zodpovědný za výpočty. Pokud při vytváření našeho nového datového typu zdědíme rozhraní, pak budeme moci předat instanci našeho datového typu jakémukoli algoritmu, který dokáže pracovat s tímto rozhraním. Implementaci rozhraní si však budeme muset napsat sami, tedy ty algoritmy, které algoritmus, který nás zajímá, použije k provádění výpočtů pomocí naší instance. Děděním třídy zároveň automaticky zdědíme již hotový kód pro rozhraní (není tomu tak vždy, nadřazená třída může bez problémů vyžadovat implementaci některých algoritmů v podřízené třídě). Tato schopnost dědit z kódu je to, co objasňuje, že v objektově orientovaném programu datový typ třídy definuje rozhraní i implementaci pro všechny jeho instance.

Stav objektu, koncept oborů, konstruktory

Jedním z problémů strukturovaného programování, se kterým se OOP potýká, je problém zachování správné hodnoty programových proměnných. Různé programové proměnné často ukládají logicky související hodnoty a za udržování této logické konektivity je zodpovědný programátor, to znamená, že konektivita není automaticky udržována. Příkladem jsou vlajky „odpáleno“ a „očekává se bonus na konci roku“, kdy podle pravidel personálního oddělení může být člověk současně nevyhozen a neočekáván bonus, nevyhozen a čekat na bonus, vyhozen a neočekávající bonus, ale nemůže být vyhozen a zároveň očekáván bonus. To znamená, že jakákoli část programu, která zaškrtává políčko „vyhozeno“, by měla vždy zrušit zaškrtnutí políčka „čekání na bonusy na konci roku“.

Dobrým způsobem, jak tento problém vyřešit, je učinit příznak „vypálený“ neměnným pro všechny části programu, kromě jedné konkrétně specifikované. V této konkrétní sekci bude vše napsáno jednou a správně a všichni ostatní budou muset na tuto sekci odkazovat, kdykoli budou chtít zaškrtnout nebo zrušit zaškrtnutí políčka „vypáleno“.

V objektově orientovaném programu bude příznak "fired" deklarován jako soukromý člen nějaké třídy a budou zapsány odpovídající veřejné metody, které jej přečtou a změní. Pravidla, která určují možnost nebo nemožnost přímo měnit jakékoli proměnné, se nazývají pravidla pro nastavení rozsahů přístupu. Slova "soukromý" a "veřejný" jsou v tomto případě takzvané " modifikátory přístupu ". Říká se jim modifikátory , protože v některých jazycích se používají ke změně dříve nastavených oprávnění, když je třída zděděna. Třídy a modifikátory přístupu společně definují přístupovou oblast, to znamená, že každá sekce kódu, v závislosti na tom, do které třídy patří, bude mít svou vlastní přístupovou oblast s ohledem na určité prvky (členy) své třídy a další třídy, včetně proměnných. , metody, funkce, konstanty atd. Existuje základní pravidlo: nic v jedné třídě nemůže vidět soukromé členy jiné třídy. Ve vztahu k jiným, složitějším pravidlům mají různé jazyky různé modifikátory přístupu a pravidla pro interakci s třídami.

Téměř každému členu třídy lze nastavit modifikátor přístupu (s výjimkou statických konstruktorů a několika dalších věcí). Většina objektově orientovaných programovacích jazyků podporuje následující modifikátory přístupu:

Problém udržení správného stavu proměnných je aktuální i pro úplně první okamžik nastavení počátečních hodnot. K tomu poskytují třídy speciální metody/funkce nazývané konstruktory. Žádný objekt (instanci třídy) nelze vytvořit jinak, než voláním kódu konstruktoru k provedení, který volajícímu vrátí vytvořenou a správně naplněnou instanci třídy. V mnoha programovacích jazycích může datový typ „struct“, podobně jako třída, obsahovat proměnné a metody, ale instance struktur, které zůstávají pouze označenou oblastí RAM, lze vytvořit obcházením konstruktorů, což je pro instance třídy zakázáno ( s výjimkou speciálních výjimečných metod pro obcházení všech podobných pravidel OOP poskytovaných v některých jazycích a platformách). To ukazuje rozdíl mezi třídami a jinými datovými typy – je vyžadováno volání konstruktoru.

Praktický přístup

V moderních objektově orientovaných programovacích jazycích (včetně php , Java , C++ , Oberon , Python , Ruby , Smalltalk , Object Pascal ) tvorba třídy spočívá v napsání nějaké struktury obsahující sadu polí a metod (mezi nimi konstruktory hrají zvláštní roli, destruktory, finalizéry). V praxi lze třídu chápat jako šablonu, podle které se vytvářejí objekty – instance této třídy. Všechny instance stejné třídy jsou vytvořeny podle stejné šablony, takže mají stejnou sadu polí a metod.

Vztahy mezi třídami

Typy tříd

Rozsah

Rozsah členů třídy (tj. rozsah kódu, ze kterého lze k nim přistupovat pod nekvalifikovaným názvem – bez uvedení názvu třídy nebo objektu) nezávisí na jejich rozsahu a je vždy stejný jako kód třídní metody.

Rozsah samotné třídy je v různých programovacích jazycích definován různě. V některých jazycích (jako je Delphi ) mají všechny třídy globální viditelnost (s přihlédnutím k viditelnosti modulu ), v jiných (jako je Java ) je rozsah třídy spojen s kompilační jednotkou, která ji obsahuje (v Javě - s balíčkem ), v jiných (jako C ++ a C# ) je rozsah třídy určen jmennými prostory ( jmennými prostory ), které jsou explicitně nastaveny programátorem a mohou, ale nemusí odpovídat kompilačním jednotkám.

Třídy v Object Pascal (prostředí Delphi)

V Delphi je třída popsána následovně:

TMyClass = class ( TObject ) private {Prvky popsané v této sekci nejsou přístupné zvenčí (mimo třídu, ale jsou dostupné v rámci modulu).} {Pole třídy se obvykle nacházejí zde.} striktně privátní {Pro Delphi 2007 a vyšší. Prvky popsané v této sekci jsou dostupné pouze v rámci třídy} chráněné {Prvky popsané v této sekci jsou dostupné pouze pro třídu a všechny její potomky.} veřejné {Prvky popsané v této sekci jsou dostupné všem.} publikováno {Prvky popsané v tomto sekce jsou dostupné všem a jsou zobrazeny v Object Inspector'e.} end ;
  • TMyClass - jméno třídy;
  • class - klíčové slovo, které spouští definici třídy (ve starších verzích bylo také klíčové slovo object);
  • TObject - třída předků, pokud existuje dědičnost ;
  • private, protected, public, published - klíčová slova definující hierarchický přístup k polím a metodám ve formě označení sekcí přístupových oblastí .

Instance ( objekt) třídy se vytvoří takto:

MojeTřída := TMojeTřída . vytvořit ;

Zničeno takto:

FreeAndNil ( MyClass ) ; NEBO MyClass . zdarma ;

Třídy v C++

Třída v C++ je vytvořena takto:

class MyClass : public ParentClass // ParentClass - třída předka, pokud existuje { veřejnost : // prvky v této sekci jsou přístupné z libovolné části programu MyClass (); // konstruktor ~ MyClass (); // chráněno destruktorem : // prvky v této sekci jsou přístupné z třídy a jejích potomků private : // prvky v této sekci jsou přístupné pouze z třídy; toto je výchozí rozsah };

Po vytvoření je třída považována za plnohodnotný datový typ , a proto jsou instance třídy vytvořeny následovně:

MyClass myinstance ;

Volání členů třídy:

moje instance . člen třídy

Instance třídy je zničena, jako každá proměnná, pouze v případě, že funkce , ve které byla vytvořena, dokončila svou práci nebo pokud byla dynamická paměť přidělená třídě násilně uvolněna .

Třídy v C#

Třídy v C# jsou definovány takto:

public class MyClass { //Člen dostupný pro jakoukoli třídu v programu public int k ; //Člen dostupný pro jakoukoli třídu ve stejném programovém modulu internal int l ; //Člen dostupný pro jakoukoli třídu ve stejném programovém modulu nebo pouze pro aktuální třídu a všechny její podtřídy v jiném modulu protected internal int m ; //Člen přístupný pouze aktuální třídě a všem jejím podtřídám protected int n ; //Člen přístupný pouze z aktuální třídy (výchozí). private int fg ; }

Na rozdíl od C++ musí být modifikátory přístupu specifikovány pro každého člena. Anonymní třídy lze definovat v metodě, jako je tato:

public void DoSomething () { var person = new { Name = "Marguerite" ; Věk = 15 ; } var pet = new { Name = "Dunya" ; Typ = "Želva" ; Majitel = osoba ; } Konzole . WriteLine ( "Věk majitele mazlíčka: " + mazlíček . Majitel . Věk ); }

Třídy v Ruby

Třídy v jazyce Ruby jsou definovány takto:

class MyClass def initialize # Konstruktor (volitelné) end public # Veřejný identifikátor je volitelný, protože nastaveno ve výchozím nastavení, # znamená, že následující metody jsou dostupné odkudkoli v programu def public_method # Public method end protected # Chráněný identifikátor označuje, že následující metody # budou dostupné pouze členům této a podřízené třídy def protected_method # Protected method end private # Soukromý identifikátor označuje, že následující metody # budou dostupné pouze členům této třídy def private_method # Private method end end

Vytvoření instance třídy:

objekt = MyClass . Nový

Zničení instance třídy není vyžadováno: děje se tak automaticky pomocí "garbage collectoru", jakmile zmizí z paměti poslední odkaz na ni.

Třídy v Pythonu

Definování třídy v Pythonu pomocí operátoru class:

class MyClass : def __init__ ( self , arg ): """Konstruktor""" self . _arg = arg # parametr objektu def metoda1 ( self , x ): """metoda zahrnutá v rozhraní třídy""" def _method2 ( self , x ): """metoda, která není součástí rozhraní třídy""" def __method2 ( self , x ): """metoda je dostupná pouze uvnitř třídy""" @staticmethod def method3 ( arg1 , arg2 , ... ): """statická metoda, kterou lze volat jak z instancí třídy, tak ze třídy samotné""" @classmethod def method4 ( cls , arg1 , arg2 , ... ): """metoda třídy, volatelná z instancí třídy i ze třídy samotné, s přístupem k interním metodám a parametrům"""

Vytvoření instance třídy:

moje instance = Moje třída ( 4 )

Explicitní zničení instance třídy není vyžadováno, protože Python má automatický "garbage collector". Můžete však explicitně odstranit odkaz na objekt (instanci třídy nebo samotnou třídu) takto:

del myinstance

Třídy v JavaScriptu

Definování třídy v JavaScriptu pomocí operátoru class:

class MojeTřída { konstruktor ( arg1 , arg2 , ...) { //konstruktor (volitelné) this . arg1 = arg1 ; toto . arg2 = arg2 ; } metoda1 () { // Běžná metoda } statická metoda { // Statická metoda } }

Vytvoření instance třídy:

var myinstance = new MyClass ( 4 , 2 )

Zničení instance třídy není vyžadováno: děje se tak automaticky pomocí „garbage collectoru“, jakmile zmizí z paměti poslední odkaz na ni.

Třídy v jazyce Java

Každá třída v Javě je obvykle vytvořena v samostatném souboru, název souboru se musí shodovat s názvem třídy. V tomto případě to bude MyClass.java

Definování třídy Java pomocí operátoru class:


class MyClass { String name = "Příklad" ; // "Konstruktor" public MyClass ( String name ) { this . jmeno = jmeno ; } // "Metoda" public String getName () { return name ; } }

Vytvoření instance třídy:

MojeTřída my = nová MojeTřída ( "Příklad 2" );

Instance třídy je automaticky zničena "garbage collectorem".

Odkazy