IB111 Programování a algoritmizace Objektově orientované programování (OOP) OP a OOP lObjekt – Kombinuje data a funkce a poskytuje určité rozhraní. lOP = objektové programování lVše musí být objekty lNapř. Smalltalk, Ruby lRelativně málo rozšířené v dnešní praxi lOOP = objektově orientované programování lObjekty jsou podporovány, ovšem ne všechno musí být nutně jen objekty. lNapř. C++, Java, … lDnes velice rozšířený přístup Terminologie lTřída lTyp objektu lObjekt lInstance třídy lStruktura – atributy (data) a metody (funkce) lZákladní vlastnosti objektů v OOP lAbstrakce lZapouzdření lPolymorfismus Základní paradigmata OOP lDatová abstrakce lZavedeme vlastní datový typ lStruktura dat lOperace nad těmito daty lOddělujeme rozhraní od implementace lZapouzdření prvků třídy lDědičnost lMožnost rozšířit existující objekty lPolymorfismus lStejné rozhraní k různým objektům (díky zděděným společným vlastnostem). Zapouzdření lStrukturální programování od sebe odděluje data a algoritmy (programový kód). lOOP data zapouzdřuje v objektech a práce s nimi je umožněna přes definované rozhraní (pomocí metod objektu). lDíky zapouzdření není třeba znát detaily implementace, ale stačí znát a používat rozhraní objektu. lDíky zapouzdření je také možné změnit implementaci pokud použijeme stejné rozhraní. lDíky „utajení“ je také možné vyhnout se chybám při náhodné nebo nesprávné přímé modifikaci dat. lUmožňuje rozdělit úkoly v týmu programátorů. Zapouzdření – příklad v C lstruct student { int narozeni_rok, narozeni_mesic, narozeni_den; float studijni_prumer; char jmeno[30]; int vypocitej_vek(); }; Zapouzdření – příklad v Pythonu lclass student: narozeni_rok, narozeni_mesic, narozeni_den = 0,0,0 studijni_prumer, jmeno = 0.0, "“ def vypocitej_vek(self): … Zapouzdření lData a metody ve třídě mohou být několika typů podle jejich „viditelnosti“ lpublic – k datům a proměnným je volný přístup lSprávný OOP program by měl ponechat public pouze metody, ne data. lprivate – metody a data nejsou přístupná z jiných částí kódu něž z metod této třídy lprotected – metody a data nejsou volně přístupné, ale jsou přístupné potomkům této třídy. Zapouzdření - příklad lePeněženka – rozhraní třídy lclass penezenka { private: int koruny, halire; public: penezenka () { koruny = halire = 0; }; void nabij (int k); BOOL zaplat (int k, int h); void vypis_aktualni_stav(); }; Zapouzdření - příklad lImplementace lvoid penezenka::nabij (int k) { koruny+=k; } lBOOL penezenka::zaplat (int k, int h) { long zbytek = koruny*100+halire – (k*100+h); if(zbytek<0) return FALSE; koruny = zbytek /100; halire = zbytek%100; return TRUE; } l Zapouzdření - příklad lPoužití: lpenezenka moje, cizi; moje.nabij(100); moje.zaplat(2,50); moje.vypis_aktualni_stav(); cizi.nabij(5); cizi.vypis_aktualni_stav(); void penezenka::nabij (int k) { koruny+=k; } moje: 100 cizi: 5 Zapouzdření - Python lclass MyClass: l i = 12345 l def f(self): l return 'hello world' l lPython nezná „private“ členy třídy lDomluva: co začíná znakem „_“ je neveřejné lSpecialitka: co začíná „__“ tak se upraví Python - příklad Dědičnost lDědičnost umožňuje rozšiřování funkčnosti třídy. lPotomek je nová třída založená na třídě původní (rodičovské). Potomek přebírá vlastnosti rodiče a může být dál rozšiřován (nová data a metody). l l Dědičnost - příklad lZákladní objekt (rodič) bude člověk. lPotomky budou student, zaměstnanec a učitel. lKaždý člověk má základní atributy jako jméno, příjmení, datum narození a adresu. lStudenti mají navíc studijní průměr, a jsou zapsáni v určitém ročníku. lZaměstnanci mají plat a ten je jim posílán na nějaký bankovní účet. lUčitelé jsou zaměstnanci, ale mají konzultační hodiny a učí nějaké předměty Dědičnost - příklad Člověk Student Zaměstnanec Učitel Příklad v Pythonu Dědičnost – příklad v C++ lclass clovek { lpublic: l char jmeno[20],prijmeni[30]; l int narozeni_rok, narozeni_masic, narozeni_den; l char adresa [100]; l int vypocitej_vek(); }; lclass student : public clovek { lpublic: l int rocnik; l float prumer; }; lclass zamestnanec : public clovek { lpublic: l int plat; l char IBAN [20]; }; lclass ucitel : public zamestnanec { lpublic: l char konzultacky[50]; l list_of_subjects *uci; }; Dědičnost – příklad v C++ lclovek c; lzamestnanec z ; lucitel u; lint v1= c.vypocitej_vek(); lint v2= z.vypocitej_vek(); lc = u; // i učitel je člověk lz = c; // NELZE – ne každý člověk je zaměstnanec Polymorfismus lPolymorfismus = jednotné zacházení s různými (polymorfními) objekty mající některé společné zděděné vlastnosti. lPolymorfismus v praxi znamená, že je možné mít různé třídy s metodami se stejnými parametry. Mohu tak odlišit chování potomků. lPozdní vazba – late binding lPolymorfismus umožňuje mít stejně pojmenované metody s různými parametry. lParametry se mohou lišit v počtu a/nebo typu. lMluvíme o tzv. přetížení metod (funkcí). Příklad v Pythonu Polymorfismus - příklad lvoid penezenka::zaplat (int k, int h) { long zbytek = koruny*100+halire – (k*100+h); if(zbytek<0) return FALSE; koruny = zbytek /100; halire = zbytek%100; return TRUE; } lvoid penezenka::zaplat (int k) { long zbytek = koruny – k; if(zbytek<0) return FALSE; koruny = zbytek; return TRUE; } lvoid penezenka::zaplat (void) { long zbytek = koruny – 10; if(zbytek<0) return FALSE; koruny = zbytek; return TRUE; } Polymorfismus - příklad lpenezenka moje; moje.nabij(100); moje.zaplat(10,0); moje.zaplat(10); moje.zaplat(); moje.vypis_aktualni_stav(); Oprátory new, delete v C++ lVytvoření objektu a jeho rušení pomocí dynamické alokace paměti. lpenezenka *moje = new penezenka; moje -> nabij(100); moje -> zaplat(5,50); delete moje; Konstruktory, destruktory lMetody, které jsou (automaticky) volány při vytváření/rušení instance objektu. lVhodné pro lInicializaci proměnných lAlokaci/dealokaci paměti Kontruktory - příklad lclass student { private: float prumer; char *jmeno; public: student () {prumer=0.0; jmeno=NULL; } student(float p,char *j) { prumer=p; jmeno = (char*)malloc(strlen(j)+1); if(jmeno)strcpy(jmeno,j); } ~student() { if(jmeno) free(jmeno); } … }; Příklad v Pythonu Přetěžování operátorů v C++ lMohu přetížit (změnit) běžné operátory lNapř. +, -, += lPřetížit lze téměř všechny operátory lNelze přetížit ., ?:, sizeof, ::, .* lPřetížení operátorů velice usnadňuje používání tříd/objektů programátory l Přetěžování operátorů - příklad lclass komplex { lpublic: l float Re, Im; l l komplex (float r, float i) { Re=r; Im=i; }; l komplex komplex::operator+=(komplex &b) l { l Re+=b.Re; Im+=b.Im; l return *this; l }; l komplex komplex::operator+(komplex &b) l { l return komplex (Re + b.Re, Im + b.Im); l }; l}; l lkomplex a(1,0), b(2,0); lkomplex c = a + b; lc+= komplex(1,5); Přetěžování operátorů v Pythonu Přetěžování operátorů v Pythonu