Post on 24-Jan-2016
description
23-04-21 1
Principy OOP• Objektově orientované programování vychá-
zí ze třech základních principů (rysů):– zapouzdření (encapsulation)– dědičnost (inheritance)– polymorfismus
23-04-21 2
Zapouzdření• Třída může obsahovat libovolné množství
členů
• Při správném objektově orientovaném přístu-pu by však měla být data skryta (zapouzdřena) uvnitř třídy
• K jednotlivým objektům by se mělo přistupo-vat prostřednictvím metod nebo vlastností
• Toto snižuje nebezpečí vzniku chyby a umož-ňuje tvůrci modifikovat vnitřní reprezentaci třídy
23-04-21 3
Dědičnost (1)• Jedná se o prostředek, který umožňuje dosáh-
nout snadné rozšiřitelnosti a znovupoužitel-nosti již existujících částí programu
• Dovoluje definovat novou třídu (B), která vznikne pouze přidáním nových členů k těm, které již byly definovány v rámci jiné třídy (A)
• Třída: – A se stává bezprostředním předkem třídy B – B je bezprostředním potomkem třídy A
23-04-21 4
Dědičnost (2)• Nechť je dána třída:class Date{
public byte Day { get; set; }public byte Month { get; set; }public short Year { get; set; }
public Date(byte d, byte m, short y) {…}public string GetDate() {…}public bool IsLeapYear() {…}
}
• Na jejím základě lze definovat jejího potomka
23-04-21 5
Dědičnost (3)• Informace o bezprostředním předkovi se zapi-
suje v definici třídy (za jejím názvem – oddě-lena dvojtečkou)
• Příklad:class DateExt : Date{
public DateExt (byte d, byte m, short y) : base(d, m, y) {…}public void AddDay() {…}public void SubtractDay() {…}private byte GetMonthDaysCount() {…}
}
23-04-21 6
Dědičnost (4)
• Jestliže třída B je potomkem třídy A, tak jsou třídě B automaticky dostupné všechny členy (vyjma konstruktorů instancí, statických kon-struktorů a destruktorů) třídy A, aniž by bylo nutné je znovu definovat
• Říkáme, že třída B dědí členy třídy A• Jestliže při definici třídy v jazyku C# neuve-
deme žádného předka, je jejím předkem auto-maticky třída object (System.Object)
23-04-21 7
Dědičnost (5)• Každá definovaná třída automaticky dědí členy
definované ve třídě object , např. metody:– Equals:
• zjistí, zda jsou si dvě instance typu object rovny
– GetHashCode:• vrací hash kód objektu, který slouží k efektivnímu
vyhledávání v hashových tabulkách
– ToString:• vrací textovou reprezentaci objektu
• Zděděné datové položky bývají obvykle inicia-lizovány vyvoláním konstruktoru předka
23-04-21 8
Dědičnost (6)
• Konstruktor předka se volá pomocí klíčového slova base, které je uvedeno za hlavičkou konstruktoru potomka (odděleno dvojtečkou)
• Příklad:public DateExt(byte d, byte m, short y) : base(d, m, y) {…}
• Pokud volání konstruktoru předka není expli-citně provedeno, pak zkouší překladač volat konstruktor implicitní
23-04-21 9
Dědičnost (7)• Tj. definice:public DateExt(byte d, byte m, short y) {…}
bude automaticky přepsána (doplněna) na tvar: public DateExt(byte d, byte m, short y) : base() {…}
• Doplněný tvar je funkční pouze v případě, že předek obsahuje (má v programu definovaný) veřejný implicitní konstruktor (v opačném případě dojde k chybě při překladu)
23-04-21 10
Dědičnost (8)
• Skrývání (maskování) metod:– dovoluje na úrovni potomka definovat metodu,
která má stejnou signaturu (stejné jméno, stejný počet a typy formálních parametrů) jako metoda na úrovni předka
– metoda potomka tak skrývá (maskuje) metodu předka
– metody, které provádějí skrývání by měly být de-finovány pomocí klíčového slova new (v opač-ném případě bude překladač vypisovat varování)
23-04-21 11
Dědičnost (9)• Platí, že proměnné typu třída A (předchůdce)
je možné přiřadit proměnnou typu třída B (následníka) – opačné přiřazení není možné
• Lze provést přiřazení tvaru:
objekt předka = objekt potomka;
• Příklad:Date d = new Date(1, 1, 2000);DateExt dExt = new DateExt(2, 8, 2010);
d = dExt;
23-04-21 12
Polymorfismus (1)• Rys umožňující, aby akce uskutečňované nad
různými objekty byly pojmenovány stejně, přičemž ale jejich realizace je různá (podle toho, nad kterým objektem se provádějí)
• Nástrojem pro realizaci polymorfismu jsou tzv. virtuální metody
• Virtuální metody:– obsahují ve své definici klíčové slovo virtual– implementace virtuálních metod může být na
úrovni potomka nahrazena implementací jinou
23-04-21 13
Polymorfismus (2)– umožňují volat různé verze stejné metody na zá-
kladě typu objektu určeného dynamicky za běhu programu
– proces nahrazení implementace zděděné virtuální metody se označuje jako předefinování (potlačení, overriding) metody
– metoda realizující odlišnou implementaci na úrov-ni potomka musí ve své definici obsahovat klíčové slovo override
– nová implementace metody (na úrovni potomka) může volat původní implementaci téže metody (na úrovni předka) pomocí klíčového slova base, jež se zapisuje v příkazové části metody
23-04-21 14
Polymorfismus (3)– poznámky:
• klíčová slova virtual a override nelze použít u soukromých (privátních) metod
• signatura metody, která provádí předefinování, musí být stejná (včetně návratového typu) jako signatura původní metody
• metoda s klíčovým slovem override je rovněž vir-tuální a může být na úrovni dalšího potomka opět pře-definována
23-04-21 15
Skrytí vs. předefinování
• Skrytí:– jedna metoda nahrazuje metodu jinou– tyto metody obvykle nemají žádnou vazbu a mo-
hou provádět zcela odlišné úlohy
• Předefinování:– zajišťuje různé implementace stejné metody– všechny implementace jsou příbuzné – provádě-
jí v zásadě stejnou úlohu, ale specifickým způ-sobem pro danou třídu
23-04-21 16
Abstraktní metody a třídy (1)• Jazyk C# dovoluje definovat tzv. abstraktní
metody
• Abstraktní metoda se definuje pomocí klíčové-ho slova abstract a neobsahuje žádnou im-plementaci
• Abstraktní metody jsou automaticky virtuální (klíčové slovo virtual se však neuvádí)
• Třída, jež obsahuje abstraktní metodu se ozna-čuje jako abstraktní třída a musí být rovněž de-finována s klíčovým abstract
23-04-21 17
Abstraktní metody a třídy (2)• Na základě abstraktní třídy nelze vytvořit no-
vou instanci:– slouží pouze jako třída, na jejímž základě budou
definovány další třídy (jako její potomci)
• Potomci abstraktní třídy provádějí předefino-vání abstraktních metod (pomocí klíčového slova override), čímž doplňují jejich imple-mentaci
• Poznámka:– jako abstraktní mohou být také označeny vlastno-
sti, indexery a události
23-04-21 18
Abstraktní metody a třídy (3)• Příklad:abstract class ShapesClass {
abstract public double GetArea(); } class Square : ShapesClass {
private double side; public Square(double n) {
side = n; } public override double GetArea() {
return side * side; }
}
23-04-21 19
Rozhraní (1)• Rozhraní (interface) definuje kontrakt s třídou
nebo strukturou, která je následně od tohoto rozhraní odvozena
• Představuje seznam členů, které se odvozená třída nebo struktura zavazuje implementovat
• Platí, že:– jedno rozhraní může dědit od jednoho nebo více
jiných rozhraní– jedna třída může implementovat jedno nebo více
rozhraní (může dědit pouze od jedné třídy)
• Dovoluje „nahradit“ vícenásobnou dědičnost
23-04-21 20
Rozhraní (2)• Umožňují třídám přidávat charakteristiky
nebo schopnosti nezávisle na hierarchii tříd• Rozhraní může obsahovat:
– metody– události– vlastnosti– indexery
• Definice rozhraní:– začíná klíčovým slovem interface, za nímž
následuje jméno rozhraní– obsahuje pouze signatury členů (nikoliv jejich
implementace)
23-04-21 21
Rozhraní (3)• Všechny členy jsou automaticky veřejné (ma-
jí přístupnost public):– klíčové slovo public se neuvádí– rozhraní udává, jak s objektem zvenku pracovat
• Jméno implementovaného rozhraní se zapisu-je za jméno třídy oddělené dvojtečkou
• Konvence:– jména rozhraní se zapisují s počátečním velkým
písmenem I
• Poznámka:– od rozhraní nelze vytvořit instanci
23-04-21 22
Rozhraní (4)• Příklad:interface IPoint{
int X { get; set; }int Y { get; set; }void WritePointCoords();
}class MyPoint : IPoint{
public int X { get; set; }public int Y { get; set; }public MyPoint(int x, int y){ X = x; Y = y; }public void WritePointCoords(){ Console.WriteLine
(”[{0}, {1}]”, X, Y);}
}
23-04-21 23
Rozšiřující metody• Umožňují rozšířit existující datový typ (třídu
nebo strukturu) dodatečnými statickými me-todami
• Tyto metody jsou okamžitě k dispozici jakým-koliv příkazům, které se odkazují na data roz-šířeného typu
• Definují se ve statické třídě
• Typ, kterého se rozšiřující metoda týká, se uvádí jako první parametr metody společně s klíčovým slovem this
23-04-21 24
Podmíněný operátor (1)• Ternární operátor umožňující zkrácený zápis
příkazové struktury if … else• Umožňuje vyhodnotit podmínku a vrátit jednu
hodnotu v závislosti na tom, je-li podmínka splněna nebo nesplněna
• Zapisovaný ve tvaru:podmínka ? splněno : nesplněnokde:– podmínka:
• booleovský výraz, který se vyhodnotí
23-04-21 25
Podmíněný operátor (2)– splněno:
• hodnota, která se vybere v případě splnění podmínky
– nesplněno:• hodnota, která se vybere v případě nesplnění podmínky
• Příklad:int x;
string s = x.ToString() + ” ”;s += (x == 1? ”člověk” : ”lidé”);Console.WriteLine(s);