Polymorfismus Dědičnost

Slides:



Advertisements
Podobné prezentace
A1PRG - Programování – Seminář Ing. Michal Typová konverze, oblast platnosti, paměťové třídy 9 Verze
Advertisements

(instance konkrétní třídy)
Seminář C++ 5. cvičení Dědičnost Ing. Jan Mikulka.
Funkce Připomeňme si program pro výpočet faktoriálu:
Pole, ukazatele a odkazy
ÚVOD DO CPP 7 Dědičnost - pokračování
BLIŽŠÍ POHLED NA TŘÍDY, DĚDIČNOST - úvod
PJV151 Vnořené a vnitřní členy mohou být členy tříd a interfejsů. Je-li X obalem Y a Y je obalem Z, pak Z získá jméno X$Y$Z - kompilací vzniknou classy.
4IT1014IT101 Pátá přednáška Datové struktury - pokračování Statické prvky třídy.
C++ Přednáška 3 Konstantní a statické členy tříd, ukazatel this, konstantní instance třídy Ing. Jiří Kulhánek , kat. 352, VŠB TU Ostrava 2004.
C# pro začátečníky Mgr. Jaromír Osčádal
Programování v C++ Cvičení.
Čtvrté cvičení Objektové programování Objektový model v Javě
J a v a Začínáme programovat Lucie Žoltá Přetěžování metod, rekurze.
J a v a Začínáme programovat Lucie Žoltá metody, objekty, konstruktor.
J a v a Začínáme programovat Lucie Žoltá. Odkazy - oficiální stránky (překladače, help, metody, vývojové prostředí NetBeans,...)
Druhá přednáška Datové typy a operátory Zapouzdření Pojem rozhraní
Rudolf Pecinovský Dědění implementace Rudolf Pecinovský
State. State – kontext a problém Kontext  chování objektu má záviset na jeho stavu, který se typicky mění za běhu Neflexibilní řešení  metody obsahují.
Páté cvičení Dědičnost Interface Abstarktní třídy a metody
4IT101 7.přednáška Třída String a regulární výrazy Algoritmy v kolekcích Vnitřní a vnořené třídy.
Ing. Josef Veselý Označení šablony a vzdělávací sady viz.rozpis.
A1PRG - Programování – Seminář Ing. Michal Operátory (2. část) 4 Verze
Třída jako zdroj funkcionality
Objektové orientované programování Objektově orientované problémy v PHP Lukáš Masopust 2008.
Objektové programování
Jedenácté cvičení Vlákna. Java cv112 Vlákna Operační systém Mutitasking – více úloh se v operačním programu vykonává „současně“ Java Multithreading -
Seminář C cvičení Obsluha výjimek Ing. Jan Mikulka.
Strategy. Strategy – „All-in-1“ na začátek class AStrategy { public: virtual void Algorithm()=0; protected: AStrategy(); }; class SpecificStrategy: public.
Rudolf Pecinovský Dědění implementace Rudolf Pecinovský
6. cvičení Polymorfismus
Počítače a programování 1
PB161 Právo friend, přetěžování operátorů, přetypování PB161 | Friend, operátory PB161 – Programování v jazyce C++ Objektově Orientované Programování.
KIV/PPA1 cvičení 8 Cvičící: Pavel Bžoch. Osnova cvičení Objekty v Javě Třída Konstruktor Metody Metody a proměnné třídy x instance Program sestávající.
OSNOVA: a) Úvod do OOPb) Třídy bez metod c) Třídy s metodamid) Konstruktory a destruktory e) Metody constf) Knihovní třídy g) Třídy ve tříděh) Přetížení.
Algoritmizace a programování Objektově orientované programování - 16 Mgr. Josef Nožička IKT Algoritmizace a programování
C# - předávání parametrů Centrum pro virtuální a moderní metody a formy vzdělávání na Obchodní akademii T.G. Masaryka, Kostelec nad Orlicí.
IB111 Programování a algoritmizace
Návrh a tvorba WWW Přednáška 5 Úvod do jazyka PHP.
OSNOVA: a) Přetížení členských funkcí b) Dědičnost tříd Jiří Šebesta Ústav radioelektroniky, FEKT VUT v Brně Počítače a programování 2 pro obor EST BPC2E.
Dědičnost - inheritance dědičnost je jednou z forem znovupoužitelnosti dědičnost je jednou z forem znovupoužitelnosti B A Třída A je předkem třídy B Třída.
13/04/20151 Datový typ třída – class (1) Datový typ definovaný uživatelem Poskytuje mechanismus pro modelování entit, s nimiž manipulují aplikace Charakterizuje.
Metodika objektového přístupu při tvorbě překladačů. Marek Běhálek Informatika a aplikovaná matematika FEI VŠB-TU Ostrava.
Šesté cvičení Výjimky Balíky.
Principy OOP Objektově orientované programování vychá-zí ze třech základních principů (rysů): zapouzdření (encapsulation) dědičnost (inheritance) polymorfismus.
Objektově orientovaný přístup (úvod)
Netrvaloppa21 Vytvořte třídu Student pro reprezentaci struktury student na ZČU. Atributy třídy budou fakulta a osobniCislo. Název třídy: Student proměnné.
PJV031 Přetypování (casting) Objekty, atributy, lokální proměnné, parametry a návratové hodnoty metod mají definovaný, neměnný typ. Jsou dva druhy typů:
Počítače a programování 1 7.přednáška. Základy Pole ve třídách a metodách Pole Arrays.
Pokročilé programování v C++ (část B)
Jazyk C A0B36PRI - PROGRAMOVÁNÍ Část II.
Strategy. Motivace Různé algoritmy pro stejnou akci Hromada kódu v mnoha podmínkách Důsledky  Komplexnost  Špatná čitelnost  Těžká správa kódu  Těžka.
Template Method. Motivační příklad – reálný svět Čaj 1) Uvař vodu 2) Dej do hrnku sáček čaje 3) Zalij hrnek 4) Přisyp cukr a vymačkej citrón Káva 1) Uvař.
Praha & EU: Investujeme do vaší budoucnosti Evropský sociální fond Gymnázium, Praha 10, Voděradská 2 Projekt OBZORY Datové typy a operátory Základní programové.
NÁZEV ŠKOLY: Střední odborná škola Net Office, spol. s r.o., Orlová-Lutyně AUTOR: Ing. Adéla Tomalová NÁZEV: Podpora výuky v technických oborech TEMA:
NÁZEV ŠKOLY: S0Š Net Office, spol. s r.o., Orlová-Lutyně AUTOR: Ing. Adéla Tomalová NÁZEV: Podpora výuky v technických oborech TEMA: Objektově orientované.
Programování OPERÁTOR SIZEOF, FUNKCE, POLE JAKO PARAMETRY FUNKCÍ ERIK KRÁL.
Programování v jazyce C++ Speciality jazyka C++, úvod do OOP.
Y36PJC Programování v jazyce C/C++
Úvod do C# - OOP Jaroslav BURDYS 4IT.
OOP - Objektově Orientované Programování
Y36PJC Programování v jazyce C/C++
NÁZEV ŠKOLY: Střední odborná škola Net Office, spol. s r. o
Návrhový vzor Flyweight
Polymorfismus = Mnohotvarost
NÁZEV ŠKOLY: Střední odborná škola Net Office, spol. s r. o
Bridge.
Reflexe jako introspekce
C# přehled vlastností.
NÁZEV ŠKOLY: S0Š Net Office, spol. s r.o., Orlová-Lutyně
Transkript prezentace:

Polymorfismus Dědičnost 4IT101 8.přednáška Polymorfismus Dědičnost

Abstraktní datový typ tři vlastnosti ADT: výhody: 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,

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

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,

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++, parametrický je z toho důvodu, že na základě parametrů se vygeneruje příslušný kód (v C++ se na základě použití šablony generuje kód), často i ve funkcionálních jazycích,

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

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)

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: 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); private List<Vcela> vcely; private List<Motyl> motyli; varianta 1 – nevýhody: duplikuje se informace o tom, zda se předává motýl či včela – je to napsáno nejen v názvu metody, ale i jako typ parametru metody, vytváří se tím velké množství metod s různými názvy, které komplikují použití.

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"); varianta 2 Metoda je poměrně složitá, je to více řádků kódu, než varianta s přetížením metod, struktura metody je složitější (přibývá rozhodování ohledně typu). Kontrola přípustných typů se přesouvá z doby překladu do běhu aplikace. Překladač povolí, aby parametrem byla instance libovolné třídy (např. String), při běhu však v tomto případě vznikne výjimka. Při použití (tj. při vkládání objektů na louku) by se měl ošetřovat vznik výjimky, tj. vzniká složitější kód i při použití této metody.

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); výhody: zjednodušuje psaní na straně použití, typově bezpečné, omezuje psaní podmínek, jednodušší kód, nevýhody: nelze jednoduše přidávat další typy použití: louka.pridej(new Vcela( ...... )); louka.pridej(new Motyl( ...... ));

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 1 – nevýhody: duplikuje se informace o tom, zda se předává motýl či včela – je to napsáno nejen v názvu metody, ale i jako typ parametru metody, vytváří se tím velké množství metod s různými názvy, které komplikují použití.

Deklarace interface [public] interface identifikátor [extends rozhraní1 [, rozhraní2 ...]] { [hlavička_metody1 ;] [hlavička_metody2 ;] … [konstanta1;] [konstanta2;] … [vnořená-třída]….. } obvykle samostatný soubor, všechny metody jsou veřejné (public), všechny konstanty jsou public static konstanty se nedoporučuje v rozhraní používat, modifikátor public nemusí být uveden public interface ObyvatelLouky { public void jednaAkce(); }

Implementace rozhraní public class Motyl implements ObyvatelLouky { public void jednaAkce () { if (naKvetineSNektarem()) { // sbirej nektar } else { preletni(); pokud nějaká metoda z rozhraní není implementovaná, je třída abstrakt metody z rozhraní musí mít modifikátor public stereotyp

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

Rozhraní umožňuje volbu implementace staticky (při překladu) i dynamicky private List <String> slova; v konstruktoru: slova = new ArrayList<String>(); private List <String> slova; v konstruktoru: if (podmínka) { slova = new ArrayList<String>(); } else { slova = new LinkedList<String>(); List je rozhraní, ArrayList a LinkedList implementují rozhraní

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

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

Dependency-Inversion Principle Moduly vyšší úrovně nesmí záviset na modulech nižší úrovně. Oba typy by měli záviset na abstrakci. Abstrakce by neměla záviset na detailech. Detaily obvykle závisí na abstrakci. Pokud modul vyšší úrovně závisí na modulu nižší úrovně, znamená to, že každá změna modulu nižší úrovně ovlivní modul vyšší úrovně. Dependency inversion - obrácení závislostí proti hierarchickému strukturovanému přístupu.

Dependency-Inversion Principle

Dědičnost v Javě

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ě

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

Terminologie Rodičovská třída Bázová třída Nadtřída Dceřiná třída předek, nadtřída, supertřída potomek, podtřída, překrytí metody, overriding přetížení metody, overloading Dceřiná třída Odvozená třída Podtřída

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 Přináší problémy při implementaci a programy jsou méně stabilní Přináší problémy při návrhu, protože nabízí návrhářům řešení, z kterého se po odhalení jeho nevýhodnosti špatně couvá Přináší problémy při modifikacích programu, protože zbytečně zvyšuje počet vzájemných vazeb, které je při modifikaci nutno respektovat

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

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

Co se vlastně dědí?

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

Vnučka Dcera Matka Object 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

Postup vytváření instance 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, Inicializují se datové atributy Zavolá se a provede konstruktor předka Provede se tělo konstruktoru

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 !!!!

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

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<String>, CharSequence

Překrývání metod INSTANCí

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

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(); …. }

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í

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.

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) {....... ...............................................................................

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

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) { ....

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

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) {....... ...............................................................................

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

Příklad s účty - překrytí metody a zapouzdření Ucet.java public void setStav (double novyStav){ stav = novyStav; } 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 boolean vyber (double castka) { if ((getStav() + limit) < castka) { return false; } else { setStav( getStav() – castka); return true; ZiroUcet.java

Přetypování referenčních typů, operátor instanceOf

Přetypování Přetypování nahoru k předkovi Přetypování dolů 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

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()); Pokus o přetypování, které nelze provést způsobí ClassCastException ClassCastException je potomkem RuntimeException Překladač není schopen odhalit, zda bude výjimka vyhozena Před přetypováním je možné použít operátor instanceof Vhodnější řešit polymorfismem !!!

Dědičnost a KONSTRUKTORY

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

Volání konstruktoru předka, super public Ucet (int noveCislo, String jmeno, double castka){ cislo = noveCislo; vlastnik = jmeno; stav = castka; } public Ucet (int noveCislo, String jmeno){ stav = 0; 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 kombinace super a this public ZiroUcet (int noveCislo, String jmeno, double castka, double limit) { super(noveCislo, jmeno,castka); this.limit = limit; }

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

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)

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