spájame
slovenskú
IT komunitu
pridaj sa
Registrácia · Login

Matúš Koprda 25.3.2011
Hodnoť článok:
1 0

Objektovo Orientované Programovanie v normálnej ľudskej reči

OOP dokáže mnoho ľudí spoľahlivo odradiť hneď na začiatku výrazmi ako dedičnosť, polymorfizmus, zapuzdrenie, abstrakcia a inými veľmi múdro znejúcimi slovami. My vám normálnou ľudskou rečou veľmi rýchlo ukážeme, že sa za tým neskrýva skutočne nič zložité.

Prečo OOP

Ako prvú si zodpovieme najdôležitejšiu vec, ktorá v mnohých návodoch a dokonca aj knihách chýba - na čo je OOP dobré a prečo ho všetci všade pchajú?

OOP dramaticky zlepšuje prehľadnosť kódu, uľahčuje jeho písanie a zvyšuje jeho znovupoužiteľnosť. Pri krátkych programoch vám toto všetko môže byť viac menej ukradnuté, ale akonáhle začnete s niečím rozsiahlejším, je to na nezaplatenie. Ak ste aj niektorí mali OOP v škole, pravdepodobne vám prišlo ako zbytočná kravina, keďže v škole sa zvyknú robiť malé programíky, kde s OOP napíšete viac kódu ako bez neho.

Tento článok je pre všetkých, čo vôbec nevedia čo je OOP alebo to vedia iba približne. Predpokladané sú veľmi základné znalosti programovania, t.j. stačí vedieť čo sú premenné, funkcie a podobne. Nebudem sa zatiaľ orientovať na žiadny konkrétny jazyk, iba na vysvetlenie pojmov, aby ste vedeli o čom je reč, keď si budete čítať nejaký konkrétny návod.

Čo je OOP

Objektovo orientované programovanie sa, nie veľmi prekvapivo, orientuje na objekty. :) Objekty sú v podstate iba štruktúry obsahujúce rôzne premenné a s nimi súvisiace funkcie.

Premenné vo vnútri objektov zvyknú byť nazývané members (dátové členy) alebo aj fields (políčka) a funkcie sa volajú methods (metódy). Prečo existujú na ne špeciálne názvy? No aby ste vedeli, že je reč o objektoch.

Napriek tomu, že hovoríme o objektovo orientovanom programovaní sa v samotných programoch málokedy stretnete s výrazom "object". Všade na vás pozerá kľúčové slovo "class", po slovensky trieda. Triedy sú vlastne šablónami, podľa ktorých sa vytvárajú objekty.

Ako vidíte na obrázku, objekty sú konkrétne výskyty (inštancie) nejakej triedy. Objekty sa navzájom líšia dátami, ktoré nesú (toto sa občas zvykne nazývať "stav objektu" - state). Napríklad, v prípade vyššie spomenutých obdĺžnikov, by sa jednotlivé objekty líšili dĺžkami strán a každý by po zavolaní metódy vypocitajObsah() vrátil svoj vlastný obsah.

Celý OOP program potom pozostáva z takýchto objektov, ktoré si volajú metódy, odborne povedané "posielajú si správy".

Malá praktická ukážka

V nasledujúcom (pseudo)kóde si môžete všimnúť špeciálne metódy s rovnakým názvom ako trieda. Sú to konštruktory, ktorých pomenovanie vychádza z toho, že sa volajú vždy keď sa vytvára/konštruuje nový objekt a slúžia na jeho inicializáciu. Vytváranie objektu ("inštanciáciu":) je vidno nižšie, v riadku s kľúčovým slovom new. Definujeme 2 konštruktory, aby sme obdĺžniky mohli vytvárať buď bez parametrov (vtedy budú mať strany dĺžku 0) alebo s dvoma parametrami.

class Obdlznik {
	float a, b; // toto su datove cleny

	// a tu nasleduju metody:
	Obdlznik() {
		a = b = 0;
	}
	Obdlznik(vyska, sirka) {
		a = vyska; b = sirka;
	}
	float vypocitajObsah() {
		return a * b;
	}
}

Obdlznik velkyObdlznik;
velkyObdlznik = new Obdlznik (15, 25);
println("Obsah velkeho obdlznika je: " + velkyObdlznik.vypocitajObsah());

velkyObdlznik.a = 1000; // chceme este vacsi a obdlznikovitejsi! ...zaruceny sposob zvacsenia vasho obdlznika ;)
println("Obsah velkeho obdlznika je: " + velkyObdlznik.vypocitajObsah());

Teraz, keď už máte predstavu čo sú objekty, prejdeme na všetky tie múdro znejúce výrazy, za ktorými sa skrývajú hlavné prednosti OOP.

Dedičnosť (Inheritance)

Jednou zo základných výhod OOP je dedičnosť. Ak ste chceli v štandardnom, procedurálnom programovaní zmeniť časť správania v určitých prípadoch, kód bolo treba znečisťovať všelijakými podmienkami. Dedičnosť toto eliminuje tak, že môžete od existujúcej triedy odvodiť ďalšiu, pričom získa všetky vlatnosti pôvodnej triedy a vy môžete poprepisovať a popridávať čo treba.

Turbo-tlačítko™ zdedilo metódu onLeftClick() a pridalo metódy, ktoré by sa mohli volať pri pravom kliku, strednom kliku, atď. Navyše prepísalo vykresľovaciu metódu obyčajného tlačítka vlastnou metódou, keďže sa neuspokojí len tak s hocijakým vzhľadom. :) Proste je náročnejšie, ale stále vychádza z rovnakého základu a správa sa podobne ako naše obyčajné tlačítko, takže ho "zdedíme".

Prepisovanie metód (v našom prípade to bola metóda kresli()) sa v originále volá "method overriding", čo je slovo mierne podobné s overloadingom. Overloading (preťažovanie) je ale niečo iné - existencia viacero funkcií(metód) s rovnakým názvom a rôznymi parametrami (príklad ste videli s konštruktormi obdĺžnika), takže pozor na vec.

Abstrakcia

Pod abstrakciou sa vo všeobecnosti chápe zameranie sa na kľúčové vlastnosti nejakého prvku reálneho sveta (alebo aj nereálneho). V OOP to zúžitkujeme to hlavne pri abstraktných triedach, čo vám ukážem na obľúbenom príklade s útvarmi, ktoré budeme vykresľovať.

Abstraktná trieda Utvar určuje, že všetky od nej odvodené triedy sa budú dať vykresliť a budú mať nejakú farbu. Abstraktná trieda sa sama o sebe nedá vytvoriť, čo dáva zmysel, lebo taký "útvar" nemá žiadnu konkrétnu podobu.

Vytvoriť sa dajú len zdedené triedy, ktoré v tomto prípade implementujú vykresľovaciu funkciu. Triedy môžu byť aj polo-abstraktné v zmysle, že môžete implementovať niektoré metódy a ostatné nechať neimplementované. Podobnou záležitosťou ako abstraktné triedy sú v niektorých jazykoch rozhrania ("interface"). Tie obsahujú iba metódy a žiadna z nich nie je implementovaná.

Polymorfizmus

A teraz to hlavné... Polymorfizmus je mechanizmus, ktorý umožňuje objektom rôznych typov odpovedať na volanie rovnakej metódy rôznym spôsobom. Z definície sa to asi zle chápe, takže opäť príklad. Predstavte si nejakú hru, kde máte svet a v ňom plno rôznych jednotiek/panáčikov/čohokoľvek. Bolo by dosť fajn, keby ich máte pokope v jednom poli, každému len poviete rozhodni sa kam máš ísť, vykresli sa, podľahni zákonom fyziky:), všetci by spravili to, čo majú a už máme hru hotovú. ;)

Vďaka polymorfizmu môžeme urobiť takú fintu, že všetky jednotky odvodíme od jednej (pravdepodobne abstraktnej) triedy, ktorá bude obsahovať všetky metódy, čo chceme pri každom volať (t.j. vykreslenie, pohyb/fyzika, rozhodovanie). Všetky odvodené jednotky potom môžeme dať do poľa abstraktného typu Jednotka a potom už len na každý prvok zavolať príslušné funkcie bez toho, aby sme riešili kto je akého typu. Polymorfizmus zabezpečí, že sa pri volaní zistí do akej triedy jednotka patrí a každá sa bude správať svojim spôsobom.

Zapuzdrenosť

Zapuzdrenie skrýva vnútorné fungovanie triedy pred ostatnými triedami. To je dobré ak chcete zabrániť používaniu vnútorných mechanizmov, ktoré by sa mohli zmeniť. Napríklad vytvoríte triedu, ktorá sa pripája na server a využíva na to určité rozhranie. Vy sa po istom čase rozhodnete, že vymeníte rozhranie za lepšie a rýchlejšie.

Ak by ste ponechali k nemu prístup všetkým programátorom, mohlo by sa stať, že nejaký chytrák™ napíše kód, ktorý priamo používa špecifické funkcie tohoto rozhrania, takže pri jeho výmene by sa celý program rozpadol. Vďaka zapuzdreniu bude obmedzený na vami sprístupnené funkcie, ktoré by ste prispôsobili zmene rozhrania a celý program funguje ďalej, ako by sa nič nezmenilo.

Takto vytvárate tzv. voľne viazané triedy, ktoré majú oveľa vyššiu znovupoužiteľnosť ako keby sa každá trieda vŕtala vo vnútorných záležitostiach iných tried.

Možno ste sa už stretli s čudnými slovami public, protected a private. To sú modifikátory prístupu - public dovoľuje prístup k metóde/údajom hocikomu, protected prvky sú dostupné iba zvnútra triedy a odvodených tried a private čisto iba z triedy samotnej. Napríklad vyššie spomínaný chytrák™ by do protected členov triedy síce nemohol zasahovať zvonka, ale mohol by z triedy odvodiť vlastnú, ktorá by to robila. V tom mu zabráni modifikátor private.

V súvislosti so zapuzdrením je často vidieť metódy getNiečo() a setNiečo(). Pamätám si ako veľmi ma iritovali a vlastne im to zostalo doteraz. :D Oni sú užitočné, ale iba ak ich ľudia nepoužívajú nasilu preto, že im niekto nahovoril aké je to kvázi "OOP-korektné". Get/set metódy majú význam v situáciách: 1) keď sa hodnota pred uložením alebo pred vrátením musí nejako spracovať a 2) ak potrebujete zamedziť prepisovaniu alebo čítaniu hodnoty. Takže ak nastane jeden z týchto prípadov alebo je čo i len malá šanca, že by mohol nastať, používajte ich, inak v pohode kašlite na to.

class Pes {
	private String meno; // ked dame psovi meno, uz ho nenaucime ine

	public Pes(String meno) {
		this.meno = meno;
	}
	public String getMeno() {
		return meno;
	}
}

Pes dunco = new Pes("Dunco");
dunco.meno = "Lolofon"; // toto by ste nemohli spravit

Pro tip: všimnite si špeciálnu premennú this. Tá obsahuje vždy inštanciu aktuálneho objektu a v tomto prípade ju používame, aby sme vedeli odlíšiť parameter "meno" a dátového člena s rovnakým názvom. Inak sa používa ak chcete inému objektu odkázať na "seba".

Statické členy

Statické členy nie sú zrovna takým piliérom OOP ako dedičnosť alebo polymorfizmus, ale používajú sa a sú vcelku užitočné. Dali by sa prirovnať ku globálnym premenným a funkciám, akurát že sú vo vnútri triedy, takže nie je v nich taký bordel. :)

class Pes {
	private String meno; // ked dame psovi meno, uz ho nenaucime ine
	private static int pocet = 0;

	public Pes(String meno) {
		this.meno = meno;
		pocet++;
	}
	public String getMeno() {
		return meno;
	}
	public static int getPocet() {
		return pocet;
	}
}

Pes dunco = new Pes("Dunco"), e3 = new Pes("Ezechiel Treti");
Pes.getPocet(); // funguje toto
dunco.getPocet(); // aj toto.. ale dava to ovela mensi zmysel

K statickým členom a metódam môžete pristupovať aj keď nemáte vytvorenú žiadnu inštanciu, dokonca môžete vytvárať celé statické triedy.

So yeah...

Je ešte tisíc vecí, čo by sa dali povedať o OOP, ale v rámci zachovania ako-tak čitateľnej dĺžky článku som sa snažil vysvetliť naozaj len to najpodstatnejšie. Detaily možno rozoberieme nabudúce. Ak by vám niečo nebolo jasné, nebojte sa ozvať v commentoch, rád to napíšem zrozumiteľnejšie. :)

Matúš Koprda Matúš Koprda

Momentálne robím internety a keď budem veľký, snáď sa dostanem aj k hrám alebo niečomu zmysluplnému. :) Mám rád minimalizmus, obskúrnu hudbu, všetko geeky a rýpanie sa v detailoch. Ďalšie kecy odo mňa nájdeš na brm.sk a na Twitteri @blade_sk.


Hodnoť článok:
1 0

9 komentárov k článku:

Komentovať môžu iba prihlásení

Zaregistruj sa cez bezplatnú registráciu alebo použi login cez Facebook (FB Connect)

Prihlás sa tu, ak už máš profil na Zajtra.sk:


Zabudol som heslo

0 3 Mike 7.12.2012 01:42:04
uplne najdebilnejsie vysvetlene OOP na svete!
0 0 Jana Mičeková 15.10.2012 10:32:09
Vynikajúci článok (zodpovedá označeniu v normálnej ľudskej reči). Súhlasím so Zuzkou nižšie, chcelo by to pokračovanie. OOP je teraz všade, človek ho nemusí vedieť nakódiť, ale musí rozumieť zdrojákom od iných a vedieť, čo urobiť, ak ich chce upraviť (napr. pri frameworkoch). Najhoršie je, že pokiaľ sa to snažíte pochopiť sami, je veľa zmätočných informácii - nedávno som čítala diskusiu o používaní objekt vs. inštancia, ako pri OOP a PHP je to objekt a tu je zase slovíčko inštancia. Viem, že je to isté, ale mätie to. Ešte raz díky
1 0 Peter Payter Gašparík 27.8.2012 04:02:52
Dobrý spôsob ako ľahko vysvetliť rozdiel medzi triedou a inštanciou je tento: Predstav si, že ideš postaviť dom, potrebuješ na to plán, z jedného plánu dokážeš postaviť viacero domov. Trieda je niečo ako tento plán, teda predpis niečoho čo sa podľa neho vytvorí, konkrétny dom je inštancia.
0 0 FrewCen 7.7.2012 08:53:12
Dosť všeobecné uvedenie, ale celkom dobré. Rozhodne tam chýba ďalších milión obmedzujúcich vecí a rozšírení. O OOP sa píšu šesťdielne biblie, nie jeden článok. Povedal by som skôr že človek ktorý toto čítal je uvedený do OOP, ale nemôže tvrdiť (ako ľudia nižšie) že OOPu rozumie a že ho chápe.

Pekný článok. Dúfam že sa pokúsiš o ďalší diel.
0 0 Andrej Halaj 1.1.2012 23:45:32
Ďakujem za skvelý článok. Vďaka nemu som konečne presne pochopil, čo je to OOP a načo slúžia také veci ako dedičnosť :). Mal som už približnú predstavu, ale tento článok mi pomohol si veci lepšie ujasniť.
0 0 Zuzka Grešla Grešlíková (fb) 10.4.2011 00:00:00
Uplne ze dakujem :D ... konecne som precitala nieco zmysluplne a nie tie kecy od vranica ktorym vobec nerozumiem :) (mam pocit ze cim povie vec zlozitejsie tym ma z toho lepsi pocit) bola by som vdacna za nejake pokracovanie lebo projekt aj tak neviem nakodit :D
0 0 Dávid 双生児 Dobiáš (fb) 9.4.2011 00:00:00
heh Valentino :D ... myslim ze toto je v celku dobre vysvetlene ako si povedal ludsky a to som potreboval akurat zacinam s Javou a toto sa mi hodi vediet :P +- som to vedel ale dobre si to zopakovat a pocut aj z ineho zdroja ze ci to naozaj chapem :) ak by si spisal nieco podobne este tak by som ani nebol proti ;)
0 0 Matúš Koprda (fb) 27.3.2011 00:00:00
lol, súdiac podľa Valentina, ty budeš asi nejaký troll z FIITky, čo? :)
ale nie, sorry, to mám z vlastnej hlavy.. šak daj nejaký awesome príklad, keď sa ti útvary nepáčia
0 0 Palo Červenka (fb) 26.3.2011 00:00:00
to snáď nie, mohli ste dať aspoň príklady iné ako tieto Valentinove sračky s útvarmi...
Zajtra.sk > Programovanie > PHP > Objektovo Orientované Programovanie v normálnej ľudskej reči


Kritika

Vieš ako robiť veci lepšie? Pomôž našim odvážnejším členom a skritizuj im projekty!

Reklama

Seriály zo Zajtra.sk

Reklama