Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

4IT101 8.přednáška PolymorfismusDědičnost. Abstraktní datový typ tři vlastnosti ADT: –lze definovat nové typy a ukrývat reprezentaci těchto typů, –lze.

Podobné prezentace


Prezentace na téma: "4IT101 8.přednáška PolymorfismusDědičnost. Abstraktní datový typ tři vlastnosti ADT: –lze definovat nové typy a ukrývat reprezentaci těchto typů, –lze."— Transkript prezentace:

1 4IT101 8.přednáška PolymorfismusDědičnost

2 Abstraktní datový typ tři vlastnosti ADT: –lze definovat nové typy a ukrývat reprezentaci těchto typů, –lze definovat množinu operací/funkcí s těmito typy –ADT je definován v jedné syntaktické jednotce, vytvářet proměnné tohoto typu lze i jinde, výhody: –klient není závislý na konkrétní implementaci ADT, –klient se nemůže „vrtat“ v ADT – přistupuje pouze prostřednictvím veřejných operací/metod; zvýšená spolehlivost,

3 Objekty požadavky na objekty: –abstraktní datový typ (zapouzdření, ukrývání implementace), třída je typ instance má k sobě přiřazeny datové atributy a metody instance, –polymorfismus a pozdní vazba, –dědičnost, překrytí metod jednonásobná x vícenásobná dědičnost

4 Pojem polymorfismus polymorfismus – mnohotvarost –biologie: existence několika forem jedinců jednoho druhu nebo populace –programování: při stejném volání metody se provádí různý kód. Který kód se provede závisí: na parametrech metod, na instanci (objektu), kterému je zpráva předávána,

5 Typy polymorfismu přetěžování metod (overloading), též ad-hoc polymorphism překrývání metod (overriding), též subtype polymorphism parametrický polymorfismus – např. šablony v C++,

6 Přetěžování metod více metod stejného jména, liší se –počtem parametrů, –typem parametrů, –pořadím parametrů static String valueOf(double d) static String valueOf(int i) static String valueOf(boolean b) static String valueOf(char c) int nextInt() int nextInt(int n)

7 Překrývání metod Každá třída, která implementuje rozhraní, překrývá všechny metody z rozhraní. Překrývání metod souvisí také s dědičností (viz dále)

8 Příklad: motýli a včely na louce dvě třídy Motyl a Vcela třetí třída Louka – úkolem je napsat metody pro přidávání motýlů a včel na louku. Máte dva seznamy: private List vcely; private List motyli; varianta 1 – dvě metody různých názvů: public void pridejMotyla (Motyl motyl) { motyli.add(motyl); } public void pridejVcelu (Vcela vcela) { vcely.add(vcela); }

9 Příklad: motýli a včely na louce 2. varianta – jedna metoda s rozskokem dle typu parametru public void pridej (Object o) { if (o instanceof Vcela) { Vcela vcela = (Vcela)o; vcely.add(vcela); } else if (o instanceof Motyl) { Motyl motyl = (Motyl)o; motyli.add(motyl); } else { throw new InvallidArgumentException( "lze vkládat pouze motýly a včely"); }

10 Příklad: motýli a včely na louce 3. varianta – přetížení metody public void pridej (Vcela vcela) { vcely.add(vcela); } public void pridej (Motyl motyl) { motyli.add(motyl); } použití: louka.pridej(new Vcela( )); louka.pridej(new Motyl( )); použití: louka.pridej(new Vcela( )); louka.pridej(new Motyl( ));

11 Příklad: motýli a včely na louce dvě třídy Motyl a Vcela třetí třída Louka – úkolem je napsat metody pro přidávání motýlů a včel na louku. varianta 4 : ve třídě Louka pouze jeden seznam, použití polymorfismu s využitím rozhraní (interface) – jedna metoda pro přidávání do seznamu, varianta 4 : ve třídě Louka pouze jeden seznam, použití polymorfismu s využitím rozhraní (interface) – jedna metoda pro přidávání do seznamu,

12 Deklarace interface [public] interface identifikátor [extends rozhraní1 [, rozhraní2...]] { [hlavička_metody1 ;] [hlavička_metody2 ;] … [konstanta1;] [konstanta2;] … [vnořená-třída]….. } public interface ObyvatelLouky { public void jednaAkce(); }

13 Implementace rozhraní public class Motyl implements ObyvatelLouky { public void jednaAkce () { if (naKvetineSNektarem()) { // sbirej nektar } else { preletni(); }

14 deklarace: private List obyvateleLouky; inicializace: obyvateleLouky = new ArrayList (); metoda pro vkládání motýlů a včel: public void pridej (ObyvatelLouky obyvatel) { obyvateleLouky.add(obyvatel); } Rozhraní a subtype polymorfismus (překrývání)

15 Rozhraní umožňuje volbu implementace staticky (při překladu) i dynamicky private List slova; v konstruktoru: slova = new ArrayList (); private List slova; v konstruktoru: if (podmínka) { slova = new ArrayList (); } else { slova = new LinkedList (); }

16 Rozhraní umožňuje předávat metody jako parametry příklad rozhraní Comparator a metoda Collections.sort()

17 Dědičnost mezi rozhraními extends v hlavičce rozhraní

18 18 Dependency-Inversion Principle a)Moduly vyšší úrovně nesmí záviset na modulech nižší úrovně. Oba typy by měli záviset na abstrakci. b)Abstrakce by neměla záviset na detailech. Detaily obvykle závisí na abstrakci.

19 19 Dependency-Inversion Principle

20 Dědičnost v Javě

21 Specializace Při práci s objekty dané třídy často odhalíme skupiny instancí se speciálními, avšak pro celou skupinu společnými vlastnostmi Příklady: –Auta můžeme dělit na osobní, nákladní, autobusy a speciální –Vesmírná tělesa dělíme na hvězdy, planety a atd. –Osoby dělíme na muže a ženy –Mezi čtyřúhelníky můžeme vydělit obdélníky, mezi nimi pak čtverce To, že je daný objekt členem speciální podskupiny nijak neovlivňuje jeho členství v původní skupině

22 Zobecnění Často provádíme obrácený myšlenkový postup: u řady různých druhů objektů nacházíme společné vlastnosti a definujeme pak společné skupiny Příklady: –Lidé spolu s řadou zvířecích druhů tvoří skupiny savců –Auta, kola, povozy, vlaky, letadla, lodě & spol. jsou dopravní prostředky –Přirozené číslo je speciálním případem celého čísla, které je speciálním případem racionálního čísla, které je speciálním případem reálného čísla, které je speciálním případem komplexního čísla –V objektově orientovaných programech je vše považováno za objekt

23 Terminologie Dceřiná třída Odvozená třída Podtřída Rodičovská třída Bázová třída Nadtřída

24 Hierarchie dědičnosti třídy v Javě mají stromovou strukturu, v jejímž kořeni je třída Object –každá třída s výjimkou třídy Object má právě jednoho předka –třída Object je společným (pra)rodičem všech tříd Na rozdíl od některých jiných jazyků (např. C++) jazyk Java nepodporuje násobnou dědičnost tříd

25 Deklarace dědičnosti klíčové slovo extends –v hlavičce třídy public class Liska extends Zvire { …. } public class CD extends AbstractPolozka { … } public class Kniha extends AbstractPolozka implements Comparable { …. } implementace rozhraní se uvádí až za deklarací dědičnosti

26 Definice dědičnosti dědictví od třídy Object se uvádět nemusí, nemá-li někdo v hlavičce uvedeného předka, je přímým potomkem třídy Object třídy z nepojmenovaného (kořenového) balíčku nemají úplný název, a proto nemohou mít potomky v jiných balíčcích

27 CO SE VLASTNĚ DĚDÍ?

28 Co se vlastně dědí? Co znamená výraz, že se něco dědí? V potomkovi mohu používat prvky předka Když vytvořím instanci potomka, tak mohu používat zděděné metody a atributy předka Potomek obsahuje všechny prvky (metody, atributy) předka

29 Aby bylo možno zabezpečit funkci všech (i soukromých) vazeb, obsahuje každý objekt třídy potomka jako svoji součást podobjekt svého předka, Objekt potomka se nemůže začít budovat dřív, než bude zcela vybudován podobjekt předka Vnučka Dcera Matka Object

30 Postup vytváření instance 1.Načtou se soubory class do paměti –nejdříve se musí načíst soubory.class předka –při nahrání souborů.class se inicializují statické prvky, 2.Inicializují se datové atributy 3.Zavolá se a provede konstruktor předka 4.Provede se tělo konstruktoru

31 Co z předka lze používat (volat) v potomkovi? Datové atributy Metody Konstruktory Statické atributy Statické metody Záleží na modifiká- torech přístupu !!!!

32 Co nabízí potomek ze svého předka? Datové atributy Metody Konstruktory Statické atributy Statické metody Záleží na modifikátorech, nesmí být překryté, pozdní vazba Záleží na modifikátorech, včasná vazba

33 Final u třídy V hlavičce třídy může být modifikátor final – nemůže mít potomky public final class String extends Object implements Serializable, Comparable, CharSequence

34 PŘEKRÝVÁNÍ METOD INSTANCÍ

35 Překrytá metoda v potomkovi je metoda se stejnou hlavičkou (jméno a parametry), jako v předkovi –metoda v potomkovi překryla metodu předka

36 Použití překryté verze metody Překrytí není předefinování ani přepsání překryté metody Při překrytí metody jinou metodou zůstává překrytá metoda nedotčená a můžete ji v potomkovi kdykoliv použít kvalifikace klíčovým slovem super public void metoda() { super.metoda(); …. }

37 Další vlastnosti překrývání metod Překrývající metoda musí mít stejnou hlavičku (název, počet parametrů a jejich typy, typ návratové hodnoty) jako metoda překrývaná nemá-li metoda stejnou hlavičku, nejedná se o překrytí, ale o přetížení

38 Příklad s účty - dědičnost Chceme vytvořit účet s možností výběru do mínusu. bude mít stejné proměnné jako třída Ucet a navíc proměnnou limit. musí se změnit metoda pro výběr z účtu.

39 Příklad s účty – dědičnost a zapouzdření public class Ucet { private int cislo; private String vlastnik; private double stav; public void vloz (double castka) { stav += castka; } public boolean vyber (double castka) { } }

40 Příklad s účty - dědičnost public class ZiroUcet extends Ucet { private double limit; public boolean vyber (double castka) { } }

41 Příklad s účty - překrytí metody public class ZiroUcet extends Ucet { public boolean vyber (double castka) {.... public class Ucet { public boolean vyber (double castka) {....

42 Příklad s účty - překrytí metody boolean vyber (double castka) { if (stav < castka) { return false; } else { stav = stav – castka; return true; } boolean vyber (double castka) { if ((stav + limit) < castka) { return false; } else { stav = stav – castka; return true; } Ucet.java ZiroUcet.java Nepře loží se, stav je privat e !!!

43 Příklad s účty – dědičnost a zapouzdření public class Ucet { private static double urok = 5.2; private int cislo; private String vlastnik; private double stav; public double getStav() { return stav; } public void vloz (double castka) { stav += castka; } public boolean vyber (double castka) { } }

44 Příklad s účty - překrytí metody boolean vyber (double castka) { if ((getStav() + limit) < castka) { return false; } else { stav = getStav() – castka; return true; }

45 Příklad s účty - překrytí metody a zapouzdření Možnosti řešení –máme možnost změnit třídu Ucet a doplníme do ní metody setStav() –nemáme možnost měnit třídu Ucet a musíme nějak použít, to co je. Použijeme metodu vloz() se záporným parametrem. Pokud ale v implementaci tuto možnost třída Ucet neumožní, nejsme schopni dědičnost využít. public void setStav (double novyStav){ stav = novyStav; } public boolean vyber (double castka) { if ((getStav() + limit) < castka) { return false; } else { setStav( getStav() – castka); return true; } Ucet.java ZiroUcet.java

46 PŘETYPOVÁNÍ REFERENČNÍCH TYPŮ, OPERÁTOR INSTANCEOF

47 Přetypování Přetypování nahoru k předkovi –probíhá automaticky –instanci jakékoli třídy lze přetypovat na typ Object Přetypování dolů –musí být v kódu uvedeno –jedná se o návrat k typu, ze kterého proběhlo přetypování směrem nahoru Object String

48 Přetypovávání, operátor instanceOf public void vypis() { for (Ucet ucet : seznam) { if (ucet instanceof ZiroUcet) { ZiroUcet ziro = (ZiroUcet) ucet; System.out.println(ziro.getVlastnik() + "\tstav: " + ziro.getStav()+"\tlimit: "+ ziro.getLimit()); } else { System.out.println(ucet.getVlastnik() + "\t" + ucet.getStav()); } Vhodnější řešit polymorfismem !!!

49 DĚDIČNOST A KONSTRUKTORY

50 Dědičnost a konstruktory Konstruktor se nedědí Při spuštění konstruktoru se jako první automaticky volá konstruktor předka, pokud neurčíme který, volá se konstruktor bez parametru. Pro určení volaného konstruktoru předka slouží klíčové slovo super

51 Volání konstruktoru předka, super Máme několik problémů –třída Ucet nemá konstruktor bez parametru –i když vytváříme GiroUcet chceme určit číslo učtu, vlastníka a případně i stav účtu, navíc určujeme limit public Ucet (int noveCislo, String jmeno, double castka){ cislo = noveCislo; vlastnik = jmeno; stav = castka; } public Ucet (int noveCislo, String jmeno){ cislo = noveCislo; vlastnik = jmeno; stav = 0; } public ZiroUcet (int noveCislo, String jmeno, double castka, double limit) { super(noveCislo, jmeno,castka); this.limit = limit; }

52 public ZiroUcet (int cisloUctu, String vlastnik, double pocatecniVklad, double limit){ super(cisloUctu, vlastnik, pocatecniVklad); this.limit = limit; } public ZiroUcet (int cisloUctu, String vlastnik, double pocatecniVklad){ this(cisloUctu, vlastnik, pocatecniVklad, 0); } public ZiroUcet (int cisloUctu, String vlastnik){ this(cisloUctu, vlastnik, 0, 0); //volání prvního konstruktoru }

53 Na co si dát u konstruktorů pozor V těle konstruktoru nesmíme volat virtuální metody, a to ani zprostředkovaně (tj. volat metodu, která volá virtuální metodu) Pokud potomek danou metodu překryje, může v překryvné verzi používat atributy, které při práci rodičovského konstruktoru ještě neexistují (přesněji nejsou ještě inicializovány)

54 Na co si dát u konstruktorů pozor V konstruktoru bychom proto měli používat pouze soukromé a konečné metody Potřebujeme-li použít virtuální (= překrytelnou) metodu, definujeme její soukromou verzi, kterou bude volat jak konstruktor, tak daná virtuální metoda


Stáhnout ppt "4IT101 8.přednáška PolymorfismusDědičnost. Abstraktní datový typ tři vlastnosti ADT: –lze definovat nové typy a ukrývat reprezentaci těchto typů, –lze."

Podobné prezentace


Reklamy Google