Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 1z 55. Rozhraní. interface (interfejs)



Podobné dokumenty
Rozhraní. interface (interfejs) Copyright Rudolf Pecinovský, Soubor: 02_Rozhrani_x_Interfejs.doc, verze , uloženo st

Metodika. Architecture First. Rudolf Pecinovský

20. Projekt Domácí mediotéka

Kolekce ArrayList. Deklarace proměnných. Import. Vytvoření prázdné kolekce. napsal Pajclín

knihovna programátora

PREPROCESOR POKRAČOVÁNÍ

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

11. Dědičnost. Dědičnost strana 103

1. Dědičnost a polymorfismus

Abstraktní třída a rozhraní

ČÁST 1. Zahřívací kolo. Co je a k čemu je návrhový vzor 33

Teoretické minimum z PJV

Mediator motivace. FontDialog. závislosti mezi jednotlivými ovládacími prvky jsou netriviální

Výčtový typ strana 67

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

PB161 Programování v jazyce C++ Přednáška 7

PB161 Programování v jazyce C++ Přednáška 7

Jazyk C# (seminář 6)

1. Programování proti rozhraní

Infrastruktura UML. Modelování struktury v UML. Superstruktura UML. Notace objektů. Diagramy objektů

Reflexe RTTI Runtime Type Identification

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

Struktura třídy, operátory, jednoduché algoritmy, junit. Programování II 2. cvičení Alena Buchalcevová

typová konverze typová inference

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

Programování v Javě I. Únor 2009

3. Je defenzivní programování technikou skrývání implementace? Vyberte jednu z nabízených možností: Pravda Nepravda

Objektově orientované programování? Co to je?

Programování II. Polymorfismus

Programování v Javě I. Leden 2008

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

Vzdělávání v egoncentru ORP Louny

Pokročilé schopnosti OOP

LED_007.c Strana: 1/5 C:\Michal\AVR\Výukové programy\archiv\ Poslední změna: :01:48

Projekt Obrázek strana 135

Programování v C++ 3, 3. cvičení

Generické programování

5 Rekurze a zásobník. Rekurzivní volání metody

2 Tvorba interaktivních grafických programů

Rámcový manuál pro práci s programem TopoL pro Windows

PŘETĚŽOVÁNÍ OPERÁTORŮ

TÉMATICKÝ OKRUH Softwarové inženýrství

Pravidla on-line výběrových řízení PROe.biz

Principy objektově orientovaného programování

Návrh aplikace. Project Westpon. Inteligentní simulátor budov. Martin Mudra, Jan Smejkal, Onřej Macoszek, Marek Žehra, Jiří Slivárich

Projekty pro výuku programování v jazyce Java

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Hladiny, barvy, typy čar, tloušťka čar. hodina 6.

Úvod do programovacích jazyků (Java)

Seznámení Corel Draw. PDF vytvořeno zkušební verzí pdffactory Pro Panel Vlastnosti. panel základních kreslicích nástrojů

Parametrizované třídy Generics generické třídy. JDK zavádí mimo jiné tzv. parametrizované třídy - generics

POČÍTAČOVÁ GRAFIKA VEKTOROVÁ GRAFIKA POKROČILÉ ČINNOSTI

Obrázek. Základní popis, zadání úkolu. Struktura tříd,

DODATEČNÉ INFORMACE Č. 1 K ZADÁVACÍM PODMÍNKÁM PŘESHRANIČNÍ INFORMAČNÍ SYSTÉM PRO PŘEDCHÁZENÍ A ŘEŠENÍ POVODNÍ A DALŠÍCH KRIZOVÝCH SITUACÍ

- příkaz pohybující želvou zpět a o kolik. vlevo 45 vl 45 libovolně zadáme) směrem doleva. Na obrázku jsme pro

Programování II. Dědičnost změna chování 2018/19

Metodická příručka pro učitele. InspIS SET modul školní testování

UŽIV ATELSKÁ PŘÍRUČKA

Vyřešené teoretické otázky do OOP ( )

Dědičnost. seskupování tříd do hierarchie. potomek získá všechny vlastnosti a metody. provádí se pomocí dvojtečky za názvem třídy.

2 Grafický výstup s využitím knihovny

Programování II. Abstraktní třída Vícenásobná dědičnost 2018/19

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Kurz Word 2000 Odrážky a číslování Kurz Word 2000 Odrážky a číslování Oddíly Záhlaví a zápatí

9. Polymorfismus a rozhraní

Třídy, polymorfismus. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

Operační systémy Linux, Mac OS X a jejich srovnání

24. listopadu 2013, Brno Připravil: David Procházka

PB161 Základy OOP. Tomáš Brukner

Technologie JavaBeans

MANUÁL K APLIKACI SOFTRADE. 1.Holandské aukce (sestupné) 2.Holandské aukce (sestupné) s možností navyšování ceny 3.Limitní cena

Programování v C++ 1, 6. cvičení

Výuka programování pro praxi

PB161 Programování v jazyce C++ Přednáška 4

KIV/PIA Semestrální práce

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Uživatelská příručka pro dodavatele

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Quo vadis programování? Automatizace vyhodnocování studentských úloh

Koncept Hayekova stroje pro řízení robotů Khepera IV

Návrhové vzory OMO, LS 2014/2015

Komponenty v.net. Obsah přednášky

RÁMCOVÁ SMLOUVA. uzavřená níže uvedeného dne, měsíce a roku mezi:

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

M I S Y S - W E B. Intranet řešení systému MISYS. Verze Příručka uživatele

TVORBA VÝROBNÍ DOKUMENTACE

Programování II. Třídy a objekty (objektová orientovanost) 2018/19

Kapitola 1: Úvodní strana PARTICLER

Jazyk C++ II. Výjimky

Pokročilé programování v jazyce C pro chemiky (C3220) Dědičnost tříd v C++

Maturitní otázka webové stránky (technologie tvorby webu) Co znamená pojem Web? Web, www stránky, celým názvem World Wide Web,

PHP framework Nette. Kapitola Úvod. 1.2 Architektura Nette

3. Třídy. Základní pojmy objektového programování. Třídy

Control Section s.r.o.

EXTRAKT z české technické normy Extrakt nenahrazuje samotnou technickou normu, je pouze informativním materiálem o normě

ZPRACOVÁNÍ NEURČITÝCH ÚDAJŮ V DATABÁZÍCH

Seminář Java IV p.1/38

Úvěrová smlouva. uzavřeli dne tuto Úvěrovou smlouvu. Hlava 1. Úvodní ustanovení a pojmy

II. kapitola Vznik pracovního poměru. 1 Pracovní smlouva

Transkript:

Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 1z 55 Rozhraní interface (interfejs)

Obsah Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 2z 55 1. Základní vlastnosti... 3 2. Návrhový vzor Služebník... 16 3. Dědění rozhraní... 24 4. Událostmi řízené programování... 40 5. PROZATÍMNÍ KONEC... 52 6. Návrhový vzor Most (Bridge)... 53 7. KONEC... 55

1. Základní vlastnosti Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 3z 55 Obsah 1.1 Rozhraní implementace... 4 1.1.1 Rozdíly... 5 1.1.2 Dvě složky rozhraní... 6 1.1.3 Příklad... 7 1.1.4 Příklad v BlueJ... 8 1.1.5 Získání dokumentace projektu... 9 1.1.6 Dokumentace knihovny CanvasManager... 10 1.1.7 Získání dokumentace v BlueJ... 11 1.2 Rozhraní interfejs... 12 1.3 Interfejs a jeho instance... 13 1.4 Příklad: Implementace interfejsu IShape... 14 1.5 Použití interfejsů... 15

1.1 Rozhraní implementace Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 4z 55

1.1.1 Rozdíly Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 5z 55 Janus římský bůh vchodů, dveří, počátku a konce Měl dvě tváře: Jedna hleděla do budoucnosti Druhá hleděla do minulosti I program má dvě tváře: Rozhraní Implementaci Rozhraní: definuje, co bude zbytek programu o dané entitě vědět Implementace: zabezpečuje, aby entita plnila svoji funkci

1.1.2 Dvě složky rozhraní Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 6z 55 I samotné rozhraní má dvě složky: signaturu kontrakt Signatura specifikuje vlastnosti, které může zkontrolovat překladač Datové typy Počty parametrů Názvy použitých entit Signatura Specifikuje vlastnosti, které může zkontrolovat překladač Kontrakt Doplňuje další důležité informace, které však překladač zkontrolovat nedokáže a o jejich dodržení se musí postarat programátor

1.1.3 Příklad Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 7z 55 Zpráva: public Ellipse(Area area, NamedColor color) Signatura: Jedná se o konstruktor, a proto je možno danou zprávu posílat pouze bezprostředně po zaslání zprávy new Ellipse Konstruktor je veřejný (public) => každému dostupný Po zaslání zprávy obdržíme objekt typu Ellipse Zpráva vyžaduje dodání dvou parametrů: První bude typu Area Druhý bude typu NamedColor Kontrakt: Oslovená třída vrátí elipsu zobrazenou na plátně umístěnou v zadané oblasti a vybarvenou zadanou barvou

1.1.4 Příklad v BlueJ Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 8z 55 Při zasílání zprávy v BlueJ: Nad dělící čarou jsou informace o rozhraní zasílané zprávy Podoba textů pod dělící čarou naznačuje, jak se zaslání zprávy zapíše v kódu Současně jsou zde informace sloužící jako nápověda k lepší identifikaci zadávaných parametrů Při zasílání zprávy vracející hodnotu se navíc zadává identifikátor proměnné, do níž bude tato hodnota uložena

1.1.5 Získání dokumentace projektu Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 9z 55 Specifikace kontraktu se stává součástí programátorské dokumentace Vývojové platformy nabízejí nástroje umožňující extrahovat tuto dokumentaci ze zdrojového kódu a publikovat v nějaké vhodné podobě Na platformě Java slouží k danému účelu program javadoc; výsledná dokumentace je vytvořena jako soustava HTML stránek Dokumentace standardní knihovny se vytváří stejně, takže pokud se vývojový tým nerozhodne modifikovat šablonu, vypadá dokumentace vyvíjeného programu stejně jako dokumentace standardní knihovny

1.1.6 Dokumentace knihovny CanvasManager Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 10 z 55

1.1.7 Získání dokumentace v BlueJ Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 11 z 55 Zadáním příkazu Project Documentation v nabídce Tools

1.2 Rozhraní interfejs Java zavedla speciální konstrukci umožňující deklarovat rozhraní bez jakékoliv zmínky o implementaci Konstrukce dostala název interface Abych mohl slovo skloňovat, budu v dalším textu používat tvar interfejs Původně to byla třída bez implementace; nyní je možno doplnit implicitní definice instančních metod + definice metod reagujících na zprávy zasílané danému typu Signatura rozhraní je dána deklaracemi metod a statických konstant Kontrakt je (stejně jako u standardních tříd) definován prostřednictvím dokumentačních komentářů Také interface je třeba přeložit, po překladu má vlastní soubor.class V diagramu tříd je doplněn stereotypem «interface» Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 12 z 55

Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 13 z 55 1.3 Interfejs a jeho instance Interfejs nemá žádnou implementaci => nemůže mít ani vlastní instance Rozhraní je jako politik či ideolog: vyhlásí, jak má něco vypadat a jak se to má chovat, ale odpracovat to musí někdo jiný Třída se může přihlásit k tomu, že implementuje daný interfejs Přihlašuje se k tomu veřejně zobrazením šipky k implementovanému interfejsu; tím se toto prohlášení stává součástí její signatury a překladač bude kontrolovat jeho naplnění Instance třídy, která implementuje nějaký interfejs, se mohou vydávat za instance daného interfejsu Třída může implementovat několik interfejsů současně, její instance se pak mohou vydávat za instance kteréhokoliv z nich Kdykoliv se hovoří o instanci interfejsu, hovoří se ve skutečnosti o instanci nějaké třídy, která daný interfejs implementuje

1.4 Příklad: Implementace interfejsu IShape Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 14 z 55 Šipka naznačující implementaci interfejsu je Čárkovaná S trojúhelníkovou hlavičkou Tvarem hlavičky se liší od šipek naznačujících vzájemné závislosti datových typů Implementaci interfejsu Zadáme klepnutím na tlačítko s obrázkem příslušné šipky a následným natažením této šipky od třídy k interfejsu Zrušíme zadáním příslušného příkazu v místní nabídce rušené implementační šipky

1.5 Použití interfejsů Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 15 z 55 Mají-li instance různých tříd některé své schopnosti společné (např. všechny umějí nastavit svoji pozici či rozměr), mají společnou jistou část svého rozhraní => Mohu definovat interfejs, který tuto společnou část specifikuje, a všechny třídy s oněmi společnými vlastnostmi prohlásí, že daný interfejs implementují = definují jím deklarované metody Pak mohu definovat metodu, která akceptuje parametry, které se vydávají (přesněji smějí se vydávat) za instance nějakého interfejsu Aby se instance třídy mohla vydávat za instanci interfejsu, nestačí, aby její mateřská třída definovala požadované metody, třída se musí k implementaci interfejsu explicitně přihlásit

2. Návrhový vzor Služebník Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 16 z 55 oblasti Obsah 2.1 Motivace... 17 2.1.1 Příklad: plynulý posun obrazců analýza... 18 2.1.2 Příklad: plynulý posun obrazců řešení... 19 2.2 Služebník implementace... 20 2.3 Způsoby využití služebníka... 21 2.3.1 Blikající světlo o obsluhu žádají instance... 22 2.3.2 Plynulý posun o obsluhu žádá klient... 23

2.1 Motivace Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 17 z 55 Několik tříd potřebuje definovat stejnou činnost a nechceme definovat na několika místech stejný kód Objekt má úkol, který naprogramovat buď neumíme, nebo bychom jej sice zvládli, ale víme, že je úloha již naprogramovaná jinde Řešení: Definujeme či získáme třídu, jejíž instance (služebníci) budou obsluhovat naše instance a řešit úkoly místo nich Řešení pak bude na jednom místě a bude se snáze spravovat Postup se hodí i tehdy, když připravujeme řešení, které chceme definovat dostatečně obecné, aby je mohli používat všichni, kteří je budou v budoucnu potřebovat, a přitom nevíme, kdo budou ti potřební

2.1.1 Příklad: plynulý posun obrazců analýza Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 18 z 55 V našem příkladu se může hodit v situaci, kdy budeme chtít definovat plynulý posun obrazců Analýza: Plynulý posun simulujeme tak, že: Obrazec zobrazíme, chvíli počkáme, aby jej uživatel zaznamenal v aktuální pozici, obrazec smažeme a posuneme dál a celou akci opakujeme, dokud jej nedostrkáme do cílové pozice Ve všech třídách, jejichž instance chceme posouvat, bychom danou metodu definovali téměř stejně Tím ale porušujeme důležitou programátorskou zásadu Don t Repeat Yourself, jež je podle své zkratky DRY občas označována jako Suchý princip Jejím porušením se namočíte do potenciálních problémů

2.1.2 Příklad: plynulý posun obrazců řešení Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 19 z 55 Řešení: Přesuneme kód na jedno místo, tj. definujeme separátní třídu, jejíž instance služebníci budou umět naše objekty na požádání plynule přesunout Přetrvávající problém: Vzhledem k typové kontrole budeme muset stále definovat více metod pro každý druh objektu jinou Řešení: Naši služebníci budou ochotní přesouvat pouze instance definovaného interfejsu, který musejí implementovat všechny třídy, jejichž instance chceme přesouvat

2.2 Služebník implementace Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 20 z 55 Služebník nepracuje sám, ale komunikuje s obsluhovanými instancemi Aby mohl instance bezproblémově obsluhovat, klade na ně požadavky, co všechno musejí umět Služebník proto: Definuje interfejs, v němž deklaruje své požadavky Jeho obslužné metody akceptují jako své parametry pouze instance deklarovaného interfejsu Instance, která chce být obsloužena: Musí implementovat daný interfejs, přesněji musí být instancí třídy implementující daný interfejs, aby se mohla vydávat za instanci tohoto interfejsu Implementací interfejsu deklaruje, že umí to, co od ní služebník k její plnohodnotné obsluze požaduje

2.3 Způsoby využití služebníka Služebník může být využit dvěma způsoby: Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 21 z 55

2.3.1 Blikající světlo o obsluhu žádají instance Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 22 z 55 Chceme po instancích třídy Light, aby uměly blikat zadanou dobu nezávisle na jiné činnosti Cyklus je nepoužitelný, protože po dobu jeho provádění ostatní činnosti stojí Takto není možno naprogramovat ukazatel směru jedoucího auta Využijeme služeb instancí třídy Repeater, jejichž metody umějí opakovat klíčové činnosti svých parametrů Instance opakovače od obsluhovaných vyžadují, aby implementovaly rozhraní Runnable s metodou run(), kterou bude opakovač zadaný-počet-krát opakovat

2.3.2 Plynulý posun o obsluhu žádá klient Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 23 z 55 Objekty projektu IShape se umí přesouvat pouze skokem Pokud bychom chtěli, aby se přesouvaly plynule, museli bychom do každého z nich přidat příslušné metody, které by však byly u všech tříd téměř totožné Seženeme si služebníka přesouvač instanci třídy Mover Služebník ví, že instance interfejsu IShape umějí prozradit a nastavit svoji pozici, a proto umožňuje zaslání zpráv, požadujících plynulý přesun instancí tohoto interfejsu

3. Dědění rozhraní Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 24 z 55 oblasti Obsah 3.1 Nadhodnocení nároků na přesouvané objekty... 26 3.1.1 Snížení nároků zavedením druhého interfejsu... 27 3.1.2 Současná implementace více interfejsů... 28 3.1.3 Výsledná podoba projektu přešipkováno... 29 3.2 Dědění... 30 3.2.1 Princip... 31 3.2.2 Tři typy dědění 1/2... 32 3.2.3 Tři typy dědění 2/2... 33 3.2.4 Implementace interfejsu opakování... 34 3.2.5 Dědění interfejsů... 35 3.2.6 Použití dědění několika interfejsů... 36 3.2.7 Množinový náhled na dědění... 37 3.2.8 Projekt se zavedeným děděním rozhraní... 38 3.3 Definice nového interfejsu, značkovací interfejs... 39 4.1 Motivace... 41 4.1.1 Vzájemně závislé objekty... 42 4.2 Nástřel řešení: vzor Prostředník... 43

4.2.1 Přetrvávající problémy... 44 4.2.2 Inverze závislostí... 45 Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 25 z 55 4.3 Návrhový vzor Pozorovatel... 46 4.3.1 Motivace... 46 4.3.2 Implementace 1/2... 47 4.3.3 Implementace 2/2... 48 4.4 Aplikace v projektu CanvasManager... 49 4.4.1 CanvasManager změny v přístupu k projektu... 50 4.4.2 CanvasManager výhody... 51

3.1 Nadhodnocení nároků na přesouvané objekty Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 26 z 55 V prvním přiblížení metody přesouvače (Mover) požadovaly parametry typu IShape; to vyžaduje schopnost reagovat na zprávy: int getx() int gety() void setposition(int x, int y) int getwidth() int getheight() void setsize(int width, int height) void paint() void rubout() IShape copy() Většinu z nich však přesouvač nehodlal poslat

3.1.1 Snížení nároků zavedením druhého interfejsu Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 27 z 55 Z předchozích zpráv posílal přesouvač pouze první tři => bylo by rozumné jej uskromnit a definovat interfejs, jehož požadavky se omezí na schopnost reakce na tyto tři zprávy Vyměníme třídu Mover instance té nové se spokojí s implementací skromnějšího interfejsu IMoveable Třídy nyní budou implementovat dva interfejsy současně, přičemž požadavky interfejsu IMovable jsou podmnožinou požadavků interfejsu IShape Obdobně můžeme přidat třídu Resizer, jejíž instance dokáží plynule měnit velikost instancí interfejsu IResizeable; třídy nyní budou implementovat tři interfejsy

3.1.2 Současná implementace více interfejsů Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 28 z 55 Parametry zpráv smějí mít jen jeden typ Budou-li plynule zvětšované objekty instancemi interfejsu IResizeable, připouštějí pouze změnu velikosti, ale ne polohy => smějí se zvětšovat pouze na jihovýchod (viz obrázek), resp. zmenšovat na severozápad Aby se mohly zvětšovat i jinam, musely by být explicitně schopny měnit i svoji polohu např. tak, že by současně implementovaly interfejs IMoveable, protože o jeho instancích se ví, že to umějí Jedinou možností je definovat interfejs (např. IChangeable), jenž by po instancích implementujících tříd vyžadoval schopnost měnit polohu i velikost

3.1.3 Výsledná podoba projektu přešipkováno Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 29 z 55 Po uvedených úpravách se projekt dostane do stavu na obrázku V tomto projektu šipky je tolik implementačních šipek, že se jednotlivé závislosti začínají ztrácet Je třeba využít konstrukci, která celý projekt zpřehlední použijeme dědění

3.2 Dědění Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 30 z 55 Dědění je jedna z klíčových konstrukcí objektového programování Bohužel, je to konstrukce, jejíž vlastnosti mnozí programátoři chápou nepřesně, aniž by si to uvědomovali, a proto zanášejí do svých programů skryté chyby Existují tři druhy dědění, nyní si probereme pouze první z nich

3.2.1 Princip Mezi instancemi nějakého typu se často najde skupina instancí se společnými speciálními vlastnostmi Notebooky či sálové počítače jsou speciální druhy počítačů Psy, kočky, koně atd. jsou speciální druhy savců HTML dokumenty jsou speciálním druhem dokumentů OOP umožňuje definovat podtyp charakterizující tuto skupinu; pro značení obou typů používáme názvy: Nadtyp Podtyp Předek Potomek Základní Odvozený typ Rodičovský Dceřiný Instance potomka přebírají rozhraní svého rodiče říkáme, že je zdědí Instance potomka jsou pouze speciální podmnožinou instancí rodiče, proto se mohou kdykoliv vydávat (alespoň formálně) za instance rodiče Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 31 z 55

3.2.2 Tři typy dědění 1/2 Dědění typů = dědění rozhraní Potomek dodrží všechny vlastnosti a schopnosti předka, tj. převezme jeho signaturu a dodrží jeho kontrakt, a může se proto kdykoliv plnohodnotně vydávat za předka Příklad: třída implementující nějaké rozhraní Dědění implementace Potomek převezme od předka jeho implementaci, takže převzaté funkce nemusí definovat sám Příklad: Všechny třídy přebírají základní metody od třídy Object Nebezpečí: při přizpůsobování zděděných entit potřebám potomka není občas dodržen kontrakt předka Přirozené dědění Jak chápeme vztah obecný speciální bez ohledu na programování Příklad: Čtverec je speciální druh obdélníku, ale nemůže se vydávat za obecný obdélník, protože namůže libovolně změnit velikost svých stran Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 32 z 55

3.2.3 Tři typy dědění 2/2 Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 33 z 55 V dobře napsaném programu jsou všechny tři typy dědění v harmonii Je-li jeden aspekt použité dědičnosti v rozporu s ostatními, narušuje se stabilita programu a jeho rozšiřitelnost Při implementaci interfejsů a při jejich dědění se uplatní pouze dědění typů, protože interfejs žádnou implementaci nemá (alespoň tak, jak jsme jej doposud probírali) Dědění implementace svádí programátory k použití, které je v rozporu s děděním typů, a proto je vykládáme až po zvládnutí dědění typů

3.2.4 Implementace interfejsu opakování Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 34 z 55 Při implementaci interfejsu se implementující třída zavazuje implementovat všechny metody deklarované v implementovaném interfejsu a dodržet jejich kontrakt Třída pak může vydávat svoje instance za instance daného interfejsu Z hlediska dědění považujeme implementovaný interfejs za předka implementující třídy, takže předchozí tvrzení můžeme považovat za speciální případ tvrzení, že instance potomka se může vydávat za instanci předka Podmínkou správné funkce je dodržení kontraktu; ten ale překladač zkontrolovat nedokáže, takže jeho dodržení a kontrola je plně na bedrech programátora

3.2.5 Dědění interfejsů Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 35 z 55 Při dědění potomek deklaruje, kdo je jeho předek V Javě smí interface deklarovat, že má několik bezprostředních předků současně public interface Potomek extends Předek1, Předek2 Potomek přebírá všechny deklarace všech předků a může přidat i svoje vlastní Třída implementující potomka interfejsu tak zákonitě implementuje každého z jeho předků => instance třídy implementující interfejs se může vydávat nejenom za instanci daného interfejsu, ale také za instanci kteréhokoliv z jeho předků

3.2.6 Použití dědění několika interfejsů Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 36 z 55 Metoda vyžaduje, aby její parametr implementoval dva různé interfejsy Java neumožňuje deklarovat, že parametr je současné instancí dvou různých typů Tuto nemožnost lze obejít tak, že definujeme interfejs, který je potomkem obou interfejsů, a deklarujeme parametr jako instanci tohoto potomka To řeší náš motivační příklad s vylepšeným plynulým měněním rozměru tvarů

3.2.7 Množinový náhled na dědění Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 37 z 55

3.2.8 Projekt se zavedeným děděním rozhraní Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 38 z 55

3.3 Definice nového interfejsu, značkovací interfejs Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 39 z 55 Interfejs vytváříme stejně jako třídu, pouze v dialogovém okně nastavíme přepínač Typ třídy (ClassType) na hodnotu Rozhraní (Interface) Implementaci interfejsu zadáme: Ručně přímým zápisem v kódu Natažením šipky od třídy k implementovanému rozhraní Značkovací interfejs (anglicky marker interface nebo tagging interface) Nevyžaduje implementaci metod Jeho implementací se třída pouze hlásí k jím deklarovanému kontraktu

4. Událostmi řízené programování Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 40 z 55 oblasti Obsah 4.1 Motivace... 41 4.1.1 Vzájemně závislé objekty... 42 4.2 Nástřel řešení: vzor Prostředník... 43 4.2.1 Přetrvávající problémy... 44 4.2.2 Inverze závislostí... 45 4.3 Návrhový vzor Pozorovatel... 46 4.3.1 Motivace... 46 4.3.2 Implementace 1/2... 47 4.3.3 Implementace 2/2... 48 4.4 Aplikace v projektu CanvasManager... 49 4.4.1 CanvasManager změny v přístupu k projektu... 50 4.4.2 CanvasManager výhody... 51

4.1 Motivace Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 41 z 55 Objekty se při pohybu nejprve smažou v původní pozici, aby se pak nakreslily v nové; při tom občas odmažou i část svých kolegů Aby objekt mohl zrekonstruovat svůj obraz, musel by mu někdo poslat zprávu Vysílač je vždy závislý na příjemci, protože změna jeho rozhraní může ovlivnit požadovaný způsob zasílání zpráv Když bude každý umět každému poslat zprávu, velmi se zvýší počet vzájemných závislostí, které zhoršují spravovatelnost Každá změna nás nutí zkontrolovat všechny závislé objekty Musí-li se změnit závislý objekt, dominovým efektem se problém propaguje na všechny objekty, které jsou na něm závislé

4.1.1 Vzájemně závislé objekty Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 42 z 55 pkg _07_Mediator T1 T5 T2 T4 T3

Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 43 z 55 4.2 Nástřel řešení: vzor Prostředník Obdobný problém byl i u telefonů obdobné je i řešení Telefony také nejsou spojeny každý s každým, ale spojují se prostřednictvím ústředny Definujeme objekt prostředníka, který zprostředkovává veškerou komunikaci objektů Vzájemné závislosti objektů se tak omezí na závislost na prostředníku pkg _07_Mediator T5 T1 Prostředník T2 V našem projektu nahradíme plátno správcem plátna Má na starosti správný vzhled Když objekt mění svoji podobu, řekne správci Správce pak požádá o překreslení všechny, jichž se to týká T4 T3

4.2.1 Přetrvávající problémy Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 44 z 55 Zavedením prostředníka snížíme počet vzájemných závislostí, avšak neodstraníme nebezpečí vzniku dominového efektu Změní-li se definice třídy komunikující s prostředníkem, musíme se podívat, nemá-li se změnit i prostředník, a pokud ano, tak se dominovým efektem rozšíří nutnost kontroly na ostatní objekty komunikující s prostředníkem Potřebujeme zabezpečit, aby prostředník na nikom nezávisel Použijeme postup uplatněný u služebníka: prostředník definuje interfejs a bude ochoten komunikovat pouze s objekty vydávajícími se za instance tohoto interfejsu Tím otočíme směr závislostí a přinutíme komunikující objekty přizpůsobit se požadavkům prostředníka, aniž by se on musel někdy přizpůsobovat jim

4.2.2 Inverze závislostí Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 45 z 55 Diagram tříd při uplatnění inverze závislostí pkg _07_Mediator Prostředník <<interface>> Komunikující T1 T2 T3 T4 T5

4.3 Návrhový vzor Pozorovatel Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 46 z 55 4.3.1 Motivace Objekt čekající na výskyt nějaké události má dvě možnosti: Neustále se ptát iniciátora události, zda už nastala Oslík v 2. dílu Shreka se neustále ptá Už tam budem? Řidič čekající na zelenou neustále sleduje semafor Dohodne se s iniciátorem, že dohodnutým způsobem oznámí, až událost nastane V lůžkovém vlaku vás průvodčí vzbudí před cílovou stanicí Řidič na semaforu v klidu čte mapu v očekávání, že ti za ním na něj zatroubí SMS oznámí příchod peněz na konto

4.3.2 Implementace 1/2 Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 47 z 55 Návrhový vzor pozorovatel řeší problém druhým způsobem, je však třeba dohodnout způsob oznámení výskytu události Vzor má několik názvů odvozených z názvů komunikujících objektů Pozorovatel (Observer) Pozorovaný (Observable) Posluchač (Listener) Vysílač (Broadcast, Sender) Vydavatel (Publisher) Předplatitel (Subscriber) Posluchač (pozorovatel, předplatitel) se musí přihlásit u vysílače (pozorovaného, vydavatele) Vysílač je ochoten přijmout přihlášku pouze od objektů implementujících jím deklarovaný interfejs definující jak objektu oznámit, že došlo k očekávané události

4.3.3 Implementace 2/2 Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 48 z 55 Posluchač se po přihlášení o událost dál nestará a hledí si svého Až vysílač zavolá dohodnutou metodu, pak zareaguje Tento přístup k řešení problému a architektury projektů bývá označován jako Událostmi řízené programování (Event driven programming) Tímto způsobem se řeší veškeré GUI a řada dalších projektů Ve vyšší podobě se používá i ve webových a aplikačních serverech

4.4 Aplikace v projektu CanvasManager Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 49 z 55

4.4.1 CanvasManager změny v přístupu k projektu Třídy, jejichž instance mají být zobrazovány na plátně, musí implementovat interfejs IPaintable Interfejs vyžaduje implementaci metody void paint(painter), kterou správce plátna (instance třídy CanvasManager) zavolá v okamžiku, kdy se má oslovený objekt nakreslit Metoda dostane v parametru kreslíře instanci třídy Painter, což je jediný objekt, který ví, kde je plátno, a umí na něj kreslit Objekt se nakreslí tak, že kreslíři vysvětlí, jak jej má nakreslit, a ten jej nakreslí Objekt, který chce být zobrazován na plátně, se musí zaregistrovat u správce plátna posláním zprávy add(ipaintable...) Objekty se kresli v pořadí, v jakém se zaregistrovaly, tj. dříve zaregistrované objekty vespod, později zaregistrované nad nimi Zpráva povoluje proměnný počet parametrů, takže lze zaregistrovat více objektů najednou, přičemž se registrují v pořadí zleva doprava Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 50 z 55

4.4.2 CanvasManager výhody Takto koncipovaný projekt umožňuje pohybovat objekty (tj. měnit jejich pozice a velikosti), aniž by to mělo vliv na kvalitu zobrazení aktuálního stavu Projekt umožňuje přidávat další třídy s dalšími schopnostmi stejně tak jako další interfejsy s dalšími požadavky Projekt se může stát základem schematického zobrazení různých simulovaných procesů Projekt funguje do jisté míry jako superplatforma, tj. platforma poskytující ekvivalentní možnosti nad různými platformami Umožňuje realizovat relativně rozsáhlé spektrum výukových úloh jen s minimálním využíváním standardní knihovny Díky tomu je převod programů mezi platformami (např. z Javy do.net či zpět) převážně věcí převodu syntaxe Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze 1.00.2413, uloženo čt 9.10.2014 12:44 51 z 55