Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /home/www/novacisko.cz/subdomains/bredy/init.php on line 11

Warning: mysql_connect(): Headers and client library minor version mismatch. Headers:50562 Library:100020 in /home/www/novacisko.cz/subdomains/bredy/init.php on line 11

Warning: Cannot modify header information - headers already sent by (output started at /home/www/novacisko.cz/subdomains/bredy/init.php:11) in /home/www/novacisko.cz/subdomains/bredy/index.php on line 38
Úvod do obecného OOP 3. díl - Bredyho blog - Ondřej Novák
Bredyho blog - Ondřej Novák

Úvod do obecného OOP 3. díl

Dědičnost


Dědičnost obecně

Když "dědíme" neznamená to nic jiného, než vezmeme vlastnosti nějakého objektu, trochu je změníme, nějaké nové přidáme a vznikne nám nový objekt. A protože tento objekt vychází z původního objektu, lze nový objekt bez problémů použít i tam, kde pracoval původní objekt.

To je hlavní přednost dědění. Můžeme v tom objevit hlavní pravidlo OOP, magické slůvko "re-use". Máme-li napsané algoritmy, které pracují s nějakými objekty, pak můžeme tyto algoritmy přesvědčit, aby pracovaly s jinými objekty. Hlavní podmínkou je, aby tyto algoritmy "nepoznaly", že pracují s jinými objekty, jinými slovy, nové objekty musí vycházet z těch původních. Musí býž potomkem

Ukažme si nyní dědění na jednoduchém grafickém vektorovém editoru v našem jazyce ByVOJ.

Obecný grafický objekt

GrObj={
+nakresliSeNa(platno) {} //obrazovka - objekt představující nějaké plátno
+transformujSe(transformace) {}
};

Objekt GrObj zde představuje hlavní vlastnosti obecného grafického objektu. Tento objekt nemá žádná data, protože v této fázi ani nevíme, co bude náš grafický objekt představovat. Ale povšimněte si důležitého poznatku. ''Bez znalosti toho, jak konkrétní objekty budou vypadat, už nyní umíme vykreslit kolekci grafických objektů na obrazovce, nebo libovolný objekt transformovat (zde myšleno transformaci v ploše).

Nyní si odvoďme jednotlivé grafické objekty

Bod=GrObj {    //dědíme Bod z grafického objektu
#p=Vector; //jeden atr
+create(x) {p=x;}
+nakresliSeNa(platno) {platno.kresliBod(p);}
+transformujSe(transformace) {p=p*transformace;} //matematická operace vektor*matice
};
Usecka=GrObj { //dědíme úsečku z grafikého objektu
#a=Vector;
#b=Vector;

+create(od,do) {a=od;b=do;}
+nakresliSeNa(platno) {platno.kresliUsecku(od,do);}
+transformujSe(transformace) {a=a*transformace;b=b*transformace;}
};
Krivka=Usecka { //křivka může za určitých situacích pracovat jako úsečka
#pa=Vector;
#pb=Vector;

+create(p1,p2,p3,p4) {super.create(p1,p4);pa=p2;pb=p3;}
+nakresliSeNa(platno) {platno.kresliBezier(a,pa,pb,b);}
+transformujSe(transformace)
{
super.transformujSe(transformace);
pa=pa*transformace;
pb=pb*transformace;
}
}
poznámka k syntaxi.
znak # představuje označení přistupu. Zde znamená, že atributy označené s tímto znakem budou přístupné jen uvnitř objektu (jako '-') ale i všem potomkům. Toto zjednušení si ale dále vysvětlíme.
objekt super zde slouží k označení, že funkce nebo atribut za ním uveden jsou z objektu, který je předkem. Více si vysvětlíme u neinstančních (třídních) atributů a funkcí.

Opravdu můžeme pokračovat v psaní dalších a další objektů. aniž bysme museli nějak měnit programy, které s nimi pracují. Pokud dodržíme jednotný přístup ke všem objektu (jednotné rozhraní), můžeme náš grafický editor libovolně rozšířovat.

Dědičnost a instance

V předchozím díle jsem naznačil, že nemusí být rozdíl mezi dědičností a instancováním. Tvrdím, že instance není ničím než potomkem šablony. Schválně se podívejme, jak bude vypadat objekt úsečky v instanci.

usecka1=Úsečka(Vector(0,1),Vector(2,1));

Dědění vs instance:

Instance
- Všechny proměnné se okopírují ze šablony do instance.
- Všechny funkce se okopírují ze šablony do instance
- Vznikne samostatný objekt.
- Objekt si zapamtuje svého tvůrce (šablonu), aby se na ní mohl později odvolávat
Dědění
- Všechny proměnné se okopírují z předka do potomka
- Všechny funkce se okopírují z předka do potomka
- Vznikne samostatný objekt.
- Objekt si zapamtuje svého předka, aby se na ně mohl později odvolávat
- Objekt je rozšířen o nové funkce a atributy, nebo některé funkce a atributy jsou nahrazeny novými verzemi.

Až na poslední řádek se instanciování a dědění neliší. Proto nadále budeme objekty vzniklé bez rozšíření o nové atributy nazývat instancemi a objekty vznikle s rozšířením potomky.

poznámka - i toto je možný vznik objektu
usecka1=Usecka(Vector(0,1),Vector(2,1)) {
#barva=Barva(1,1,0);
}
Objekt vzniká tak že dědí objekt Usecka tak že jeho část inicializuje konstruktorem. Poté jej rozšíří o nový atribut barva - je to instance nebo potomek? Sami vidíte, že záleží na kontextu.

Neinstanční (sdílené) atributy a funkce

V předchozím odstavci se mluví o kopírování. V tomto případě je to trochu nepřesné. Atributy se zcela jistě kopírují, protože vznikem potomka nebo instance vzniká úplně nový objekt, který musí pracovat samostatně. Je otázka zda musíme kopírovat i funkce.

V OOP se to běžně nedělá, protože se nepředpokládá, že by se funkce měnily za běhu. Častější je, když funkce potomek sdílí od svého předka nebo když instance funkce sdílí od své šablony. V objektu pak funkce neexistuje fyzicky, ale je zde jen odkaz na předka, který funkci obsahuje.

Při zpracování funkce se vždy pracuje s tím objektem, který byl použit, přestože vlastní funkce byla definována pro některého předka. Tato skutečnost je známa, a proto může fungovat klíčové slovo super, které se odkáže na funkce, která je definována v kontextu předka relativně vůči aktuální funkci. Všimněte si, že nezáleží na kontextu objektu, který je ve funkci zpracováván.

Ukažme si to na příkladu:

BarevnaKrivka=Krivka {
#barva=Barva;

+create(p1,p2,p3,p4,b) {super.create(p1,p2,p3,p4);b=barva;}
nakresliSeNa(platno)
{
staraBarva=platno.nastavBarvu(barva); //neprve nastavime barvu kreslení
super.nakresliSeNa(platno); //kleslíme
platno.nastavBarvu(staraBarva); //vrať původní barvu
}
};

Nadefinovali jsme si objekt barevné křivky, které můžeme určit barvu. Používáme zde dvakrát slovíčko super. Ve skutčnosti je zde víckrát, potřetí jej najdeme ve funkci tranformujSe v předkovi Krivka, konečně, vyskytuje se zde víckrát.

bk1=BarevnaKrivka(Vector(0,0),Vector(0,1),Vector(3,1),Vector(3,0),Barva(1,0,0));
bk1.nakresliSe(platno);

Jak se nyní bude pracovat se super? Protože funkce nakresliSe v objektu bk1 je zděděná z objektu BarvnaKrivka, je tato funkce volána v kontextu objektu BarevnaKrivka i přesto, že aktuálním objektem je bk1. Jinými slovy, funkce pracuje s objektem bk1, ale jako by pracovala s objektem BarvnaKrivka - dokonce si funkce myslí, že je to objekt BarvnaKrivka. při zavolání funkce nakresliSe dojde tedy nastavení barvy a poté volání té samé funkce přes super tedy v předkovi. Jenže zde se nemyslí předek objektu bk1 ale předek objektu BarvnaKrivka což je objekt Křivka

Kdyby funkce nebyla sdílená, ale okopírována (v jazyce ByVOJ to také lze), byl by předkem objekt BarevnaKrivka

Tyto pravidla nemusí být nutně vztažena jen na funkce. I atributy mohou být sdílené. Jednoduchý příklad:

BaseObj={
^#counter=0; //^ znamená sdílená, # znamená veřejná pro potomky

+dejCitac() {return counter;}
};
DerivedObj={
+citej() {counter=counter+1;}
};
instance1=DerviedObj;
instance2=BaseObj;
instance1.citej();
instance1.citej();
x=instance2.dejCitac(); //jaká zde bude hodnota?

Správná odpověď je 2. Atribut counter vzniká při vzniku objektu BaseObj. Všechny vznikající instance a potomci jej pouze sdílí. Proto se změna jeho hodnoty projeví ve všech potomcích.

V případě že

DerivedObj2=DeriveObj {
#counter=0;
+dejCitac() {return counter;}
+dejCitacBase() {return super.counter;}
}
instance3=DerivedObj2;
a=instance3.dejCitac(); //vysledek 0
b=instance3.dejCitacBase(); //vysledek 2

I přesto, že existuje atribut counter, který překryje původní sdílený atribut, mohu přes objekt super přistoupit k původnímu atributu counter a přečíst si jeho hodnotu.

poznámka
Využití objektu super je širší. Mohu takto například číst či měnit atributy šablony předka.
V jazyce ByVOJ existují ještě další speciální objekty. Tady je jejich celý výčet.
this
alias objektu, který je ve funkci zpracováván.
creator
objekt představuje odkaz na tvůrce tohoto objektu. Je to buď předek, nebo šablona. Umožňuje přistupovat na atributy šablony, nebo volat funkce šablony, přestože instance obsahuje novou verzi.
current
objekt představuje odkaz na objekt, v němž je definována aktuálně zpracovávána funkce. Přes tento objekt lze volat funkce definované ve stejné objektu, přestože this obsahuje jejich nové varianty.
super
objekt představuje odkaz na objekt předka relativně objektu, v němž je definována aktuálně zpracovávána funkce. Přes tento objekt lze volat funkce definované předkem objektu, přestože this obsahuje jejich nové varianty.
creator(objekt), super(objekt)
při vícenásobné dědičnosti lze rozlišit, kterého předka má objekt představovat
vytvořeno: 19.6.2006 09:29:44, změněno: 19.6.2006 11:16:44
Jsou informace v článku pro Vás užitečné?
  • (1)
  • (2)
  • (1)
  • (0)
  • (1)
Nick nebo OpenID
Vzkaz
 
25.7.2016 18:39:16

NOKhlSsod5N

Plichu ma rację jak minimal to minimal. Kernel + Gnome-Core + Narzędia i to powinno starczyć. I jeszcze powiedzcie mi w ktay;cute&roch zaawansowanych dystrybucjach mamy zainstalowany Gstreamer i Flash na starcie?

Podobné články

Úvod do obecného OOP 2. díl

V tomto díle prozkoumáme život objektů

Úvod do obecného OOP 1. díl

V tomto seriálu bych se chtěl věnovat obecnému OOP. První díl budiž predmluvou a vymezením pojmů.

Serializace dat a objektů

Následující článek je úvodem do další série o generickém programování (šablony), nyní se zaměříme na problém perzistentního ukládání dat nebo jejich transport, obecně o serializaci a deserializaci dat

GarbageCollector v C++, prototyp

Neustále slýchám, jak v C++ chybí Garbage Collector. Ač si o tomto nástroji myslím své, a v zásadě jsem proti zavedení GC v C++, přijal jsem tyto nářky jako výzvu.

Distributor - vaše objekty budou o svém okolí vědět vše

Největším problémem většiny UI /ale i ne-IU/ aplikací, které potkávám, je špatná nebo vůbec nevyřešená komunikace mezi důležitými objekty. Přitom stačí málo, obstarat si distributora.
Reklama: