46
@RoboNovotny UINF/PAZ1c epizóda 6 21/okt/15

UINF/PAZ1c 6novotnyr/home/skola/programovanie... · 2015. 12. 9. · Zapúzdrenie / encapsulation. Proces ,,zaškatuľkovania" elementov abstrakcie, ktoré tvoria jej štruktúru

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

  • @RoboNovotnyUINF/PAZ1c epizóda 621/okt/15

    PresenterPresentation Noteshttps://en.wikipedia.org/wiki/Iron_pillar_of_Delhi#/media/File:QtubIronPillar.JPG

  • dedičnosť• trieda vie rozšíriť

    či zmeniť správanie nadradenej triedy

    polymorfizmus• objekty danej triedy sa môžu

    správať všelijako v závislosti od konkrétneho typu

    zapuzdrenie• triedy sú uzavreté

    skrinky s jasne určenými operáciami

  • Zapúzdrenie / encapsulation

    Proces ,,zaškatuľkovania" elementov abstrakcie, ktoré tvoria jej štruktúru a správanie. Účelom

    zapúzdrenia je oddeliť rozhranie s kontraktom abstrakcie od jej implementácie.

    – Grady Booch, Object-Oriented Analysis and Design with Applications, 2007

  • Zapúzdrenie

    • štruktúra = stav = inštančné premenné• správanie = schopnosti = metódy• „zaškatuľkovaný” element abstrakcie = trieda• kontrakt = hlavičky metód

    – formálna syntax pre to, čo očakávame od triedy• implementácia = kód v metódach

    Proces ,,zaškatuľkovania" elementov abstrakcie, ktoré tvoria jej štruktúru a správanie. Účelom zapúzdrenia je oddeliť rozhranie s

    kontraktom abstrakcie od jej implementácie.

  • Kontrakt = interfejs

    interface CitatyDao {Citat najdiPodlaId(Integer id);List najdiPodlaAutora(String autor);void pridaj(Citat citat);List vratVsetky();List najdiPodlaKlucovehoSlova(String dopyt)

    }

    CitatyDao citatyDao = ...for(Citat c: citatyDao.vratVsetky()) {…

    }

  • trieda• záruky správania a

    predpoklady, na ktoré sa môže používateľ triedy spoliehať

    • očakávania používateľa, ktoré mu trieda naplní

    • zodpovednosti triedy\

    klient• záruky korektného

    správania sa používateľa

    • splnenie predpokladov pre použitie triedy

    Kontrakt: medzi triedou a klientom

    kontrakt

  • Kontrakt je definovaný...

    hlavičky metód

    parametre + ich typy

    návratová hodnota + typ

    výnimky

    stav triedy

    precondition

    postconditions

    invarianty

  • Príklad: metóda pridaj()

    • metóda nevracia nič• vstupom je jeden citát

    – ľubovoľný, nie nullový• výnimky: nullový kontakt, duplicitný kontakt

    interface CitatDao {void pridaj(Citat citat);Citat najdiPodlaId(Integer id);List najdiVsetky():…

    }

  • Kontrakt definuje vlastnosti funkcie

    • metóda je akási matematická funkcia• s definičným oborom

    – parametre a ich typy• s oborom hodnôt

    – návratová hodnota• s definíciou správania, ak príde hodnota mimo

    definičného oboru

    interface MatematickeOperacie {double odmocnina(double cislo);

    }

  • *-conditions, invarianty

    • výrok, ktorý musí byť pravdivý pred zavolaním metódyprecondition

    • výrok, ktorý musí byť pravdivý po dobehnutí metódypostcondition

    • výrok pravdivý vždy vzhľadom k triede• „nemenná vlastnosť“• obvykle od stvorenia objektu

    invariant

  • Príklad

    • precondition:– citát nie je null– citát ešte neexistuje v zozname

    • postcondition:– citát sa ocitne v zozname

    • invariant:– ostatné citáty sa nezmenia– ...

    void pridaj(Citat citat);

  • Overenie *conditions

    • narušenie preconditions a postconditions = výnimka

    • konvencia v Jave: – hodíme runtime výnimku– vlastnú alebo niektorú z preddefinovaných

    IllegalArgumentExceptionNesprávna alebo nepovolená hodnota parametra = narušenie precondition

    NullPointerException Niekde sa objavilo null (na vstupe?)

    IllegalStateExceptionTrieda sa dostala do stavu, ktorý narúša invariant

  • Výnimky v kontraktoch

    • výnimky v kontraktoch by mali byť zmysluplné• typické runtime výnimky

    – odporúča sa ich vymenovať• alebo vlastné, zodpovedajúce miere abstrakcie

    interface Pekáreň {Koláč upeč(Recept r)

    throws FileNotFoundException}

    ZláSurovinaExceptionNekorektnýReceptException

  • Dokumentovať!

    • pre/post-conditions a invarianty je dobré zadokumentovať– aby používateľ vedel, čo čakať– a nebol prekvapený...

  • Nezverejňujte vnútornú štruktúru triedy.

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • • trieda = black box• všetko schované za public metódami• najlepšie je schovať všetko za interfejs

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • Nezverejňujte detaily o internom stave triedy.

    class BankovýÚčet {public int zostatok;

    }BankovyUcet ucet = new BankovyUcet();ucet.zostatok = -Integer.MIN_VALUE;

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • Nezverejňujte detaily o internom stave triedy.

    • používajte modifikátory viditeľnosti• všetky inštančné premenné = private!

    – ak treba, uvoľňujte reštrikcie• prístup k inštančným premenným cez gettre

    a settre• zistite, či naozaj ich treba.

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • Nezverejňujte rozdiel medzi uloženým a vypočítaným stavom.

    Nezverejňujte implementačné detaily triedy.

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • Zásady pre zapúzdrenie

    Dáta a operácie nad nimi nech sú v rovnakej triede.

    class Bod { int x; int y }

    class BodUtils {static double vzdialenost(Bod b1, bod b2) { ... }

    }

    class Bod {int x; int y;public double vzdialenost(Bod bod) { ... }

    }

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • Zásady pre zapúzdrenie

    Zoskupovanie dát a operácií do tried realizujte na základe zodpovednosti, ktoré triedam určíte.

    class Bod {int x; int y;double jeVnútri(Útvar u) { ... }

    }

    class Útvar {boolean obsahujeBod(Bod b) { ... }

    }

    PresenterPresentation Noteshttp://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export/home/httpd/javaworld/javaworld/jw-05-2001/jw-0518-encapsulation.html&pagename=/javaworld/jw-05-2001/jw-0518-encapsulation.html&pageurl=http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html&site=jw_core

  • 1. použite interfejs2. vytvorte triedu, ktorá ho implementuje3. pred každú inštančnú premennú dopíšte

    private4. gettre a settre len ak ich naozaj treba

  • využitie iných tried

    hybrid kompozície

    a dedičnosti

    odvodzovanie z inej triedy

    kompozícia dedičnosť

    delegácia

  • Dedičnosť (is-a)

    Trieda prevezme správanie od svojho rodiča, dokáže ho obohatiť a resp. pozmeniť.

    Karol IV. (1685-1740)rímsky cisár, kráľ Uhorska, Česka,

    Španielska, rakúsky arcivojvoda...

    Mária Terézia (1717, 1780)rímska cisárovná, kráľ ovná

    Uhorska, Česka, rakúska arcivojvodkyňa...

  • Dedičnosť (is-a)

    Trieda prevezme správanie od svojho rodiča, dokáže ho obohatiť a resp. pozmeniť.

    nové metódy prekrývanie / overriding

    dedičnosť metód

  • Dedičnosť (inheritance, is-a)

    Auto je vozidlo, ktoré je motorové, dvojstopové a poháňané benzínom.

    Človek je dvojnožec, ktorý nemá perie.-- Platón, Politikus, 4. stor. pnl

  • Uprednostňujte kompozíciu pred dedičnosťou!

    -- Gang of Four, autori Design Patterns

  • Sanity check! Kontrola zdravého rozumu

    Ak slovenská veta „každý X je aj Y“ neznie prirodzene, nie je to dedičnosť!

    Každý spojový zoznam LinkedList je zoznamom List.

  • Aj majster tesár

    ― P. Herout, Učebnice jazyka Java (2001)

  • Aj majster tesár

  • • hovorí sa len o dedičnosti metód• v praxi sa hodí aj dedičnosť inštančných

    premenných– modifikátor viditeľnosti protected

    • treba veľmi opatrne!– budú príklady..

  • Dediť či nedediť?

    • naozaj je vzťah is-a?• implementujete interfejs / dedíte od

    interfejsu?• je rodič explicitne navrhnutý na dedenie?• máte dosah na implementáciu [zdrojáky]

    rodičovských tried?• dedíte od tried v rovnakom balíčku?

    PresenterPresentation NotesRobert Roth (Hamlet). Filip Vančo, 2007

  • Uprednostňujte kompozíciu pred dedičnosťou!

    -- Gang of Four, autori Design Patterns

  • PresenterPresentation Noteshttp://dvg4ol0hclm7o.cloudfront.net/content/royprsb/early/2011/04/05/rspb.2011.0401/F1.large.jpg

  • objekt istej triedy sa dá používať ako objekt rodičovskej triedy

  • interface Door {boolean permit(Animal a)

    }

    Animal dog = new Dog();door.permit(dog);

    Animal whale = new Whale();door.permit(whale);

  • možno prekrývať metódy rodičovskej triedy.

    počas behu programu sa rozhodne, na ktorom objekte

    sa metóda naozaj zavolá.

  • Animal pet = new Crocodile();System.out.println(pet.guard());

    Animal pet = new Dog();System.out.println(pet.guard());

  • metóda, ktorú možno prekryť v podtriede

  • všetky* metódy sú virtuálne

    *public | protected | abstract | nie static | nie final

  • 1) zisti triedu objektu2a) ak je na nej príslušná

    metóda, zavolaj ju2b) ak nie, pozri sa do rodiča a

    GOTO 1)

    * pre public | protected | abstract | nie static | nie final

  • implementované pomocou tabuľky virtuálnych metód

    (vtable)

  • Slide Number 1Slide Number 2Zapúzdrenie / encapsulationZapúzdrenieKontrakt = interfejsKontrakt: medzi triedou a klientomKontrakt je definovaný...Príklad: metóda pridaj()Kontrakt definuje vlastnosti funkcie*-conditions, invariantyPríkladOverenie *conditionsVýnimky v kontraktochDokumentovať!Slide Number 15Slide Number 16Slide Number 17Slide Number 18Slide Number 19Slide Number 20Zásady pre zapúzdrenieZásady pre zapúzdrenieSlide Number 23Slide Number 24Slide Number 25Dedičnosť (is-a)Dedičnosť (is-a)Dedičnosť (inheritance, is-a)Slide Number 29Sanity check! Kontrola zdravého rozumuAj majster tesárAj majster tesárSlide Number 33Dediť či nedediť?Slide Number 35Slide Number 36Slide Number 37Slide Number 38Slide Number 39Slide Number 40Slide Number 41Slide Number 42Slide Number 43Slide Number 44Slide Number 45Slide Number 46