Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti
Programování v jazyku Java základy OOP
BI-PJV Programování v jazyku Java Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké učení technické
Klíčová slova - abecedně Klíčová slova jsou jen z malých písmen: – – – – – – – – – –
abstract boolean break byte case catch char class const * continue
– literály:
default do double else extends final finally float for goto *
if implements import instanceof int interface long native new package
private this protected throw public throws return transient short try static void strictfp volatile super while switch synchronized
false true null
* - vyhrazená - leč nefunkční assert - od verze 1.4 enum - od verze 1.5 Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
2/54
Klíčová slova dle užití typy: primitivní(8): boolean byte short int long char float double literály: false true null řídící příkazy: if else for do while break continue switch case default return pro výjimky: throw try catch finally, od verze 1.4: assert operátory: instanceof new this super strukturální: package import class interface extends implements od verze 1.5: enum modifikátory: přístupu: public protected “friend“ private final static jen proměnných: transient volatile jen metod: void throws synchronized native strictfp jen metod a tříd: abstract nefunkční: const goto Pozn: toto rozdělení není přesně dle specifikace Javy. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
3/54
Objektově Orientované Programování Programovat lze klasicky neobjektově - tedy s využitím jen primitivních typů a statického kontextu - tj. statických atributů, statických metod, statických inicializátorů a výčtů. Leč objektová metodika ( analýza OOA, design OOD, programování OOP ), výrazně usnadňuje vytváření složitého softwaru. Objektový přístup je velmi přirozený, neboť pohlíží na softwarové entity a vztahy často tak, jako by byly z materiálního světa, což programátorům usnadňuje pochopení a tvorbu konstrukcí pomocí analogií. Java vyniká těmito důležitými rysy: • Zavedení jasného pořádku a etikety. • Přísné typování jmen.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
4/54
Objektově Orientované Programování 1.
Abstrakci (abstraction), tj. zobecnění pohledů a částečná řešení.
2.
Dědičnost (inheritance), tj. získávání vlastností a schopností děděním z vhodné třídy a případně i dat nebo částečných požadavků z interfejsů.
3.
Polymorfismus (polymorphism), tj. jednotné zacházení s různými (mnohotvarými) objekty mající některé společné zděděné schopnosti.
4.
Zapouzdření (encapsulation), tj. skrývání části tříd a interfejsů.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
5/54
Třídy a objekty Věci okolo nás lze hierarchizovat do tříd (konceptů). Každá třída je reprezentována svými prvky, objekty dané třídy Každá třída je charakterizována svými vlastnostmi, svými funkčními možnostmi a svými parametry Příklad: Třída „automobil“ • Funční možnosti automobilu – metody pro ovládání • Parametry – charakteristická data
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
6/54
Třída - programová jednotka k řešení problému •
Třída v jazyku Java je programová jednotka tvořená množinou identifikátorů, které mají třídou definovaný význam: – data – proměnné, konstanty (členské proměnné, datové složky, atributy) – metody - funkce a procedury
•
Takto koncipovaná třída je zdrojem funkcí popisujících řešení problému rozkladem na podproblémy
Jiný pohled na třídu • Základem uživatelského programu v jazyku Java je třída, ve které – musí být deklarována hlavní funkce main – mohou být deklarovány další funkce (procedury) třídy – mohou být deklarovány statické proměnné, které jsou použitelné jako nelokální proměnné ve funkcích dané třídy Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
7/54
Třída a objekty - příklad METODY: zrychlit, brzdit, zatočit, zastavit;…
TŘÍDA: AUTO
definice
DATA:jmeno,barva, maxRychlost, prumSpotreba, klimatizace
objekt: autíčko
objekt: beruška
objekt: závodní
objekt: auťák instance
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
8/54
Třída Auto - struktura public class Auto { String barva; …..
public class Auto(){ } ……
data
konstruktory
metody public void startuj(){ }
} Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
9/54
Datové objekty typu třída •
Obecně je třída popisem strukturovaného datového typu, tzn. specifikuje • množinu hodnot datových objektů skládajících se ze složek (datových) • množinu operací s datovými objekty
• •
Třída je „šablona“ - vzor pro vytváření jednotlivých objektů (instancí) Datové objekty typu třída (zkráceně jen objekty) se nazývají též instancemi třídy • V jazyku Java lze objekty (instance tříd) vytvářet pouze dynamicky pomocí operátoru new a přistupovat k nim pomocí referenčních proměnných (podobně jako u pole)
objekt, instance třídy referenční proměnná
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
10/54
Objekty, základní pojmy • Objekt - datový prvek, instance třídy, dynamicky vytvořen podle „vzoru“- třídy • Objekt (resp. data) je strukturován tzn. skládá se z jednotlivých položek Pozn. 1: Třída bez vytvořené instance (objektu) nemůže „pracovat“ (mohou být použity jen její statické metody či proměnné), instance musí být vytvořena pomocí new Pozn. 2: Existují dva druhy neprimitivních datových typů (referencované): – objekty ~ heterogenní objekt skládající se z položek různého typu – pole ~ homogenní objekt skládající se z položek stejného typu Pozn.3:Položky objektu označujeme též jako • členské proměnné (member variables) • datové složky • atributy objektu Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
11/54
Třída – příklad Třída je návrhový vzor - definuje vlastnosti a chování vlastnosti …. atributy chování …. metody (funkce a procedury)
Příklad obdélník - popisuje objekty „reálného světa“ atributy (vlastnosti): • • • •
šířka, výška, barva, pozice na obrazovce, …
metody (chování, reakce na požadavky okolí) • nastavení barvy, • výpočet obvodu, obsahu, • posunutí, …
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
12/54
Obdélník - příklad definice třídy Jméno třídy začíná velkým písmenem public class Obdelnik { Color barva; int sirka, vyska; Atributy objektu - definují typ a Point pozice; jména vlastností int vypoctiObvod(){ return 2*(sirka+vyska); } int vypoctiObsah(){ return sirka*vyska; Metody objektu - definují chování, } schopnosti, reakce void setBarvu(Color c){ barva = c; } }
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
13/54
Speciální metoda - konstruktor třídy public class Obdelnik { … Obdelnik(int s, int v){ sirka = s; vyska = v; } } Konstruktor: • tato metoda vytvoří objekt • nastavuje vlastnosti objektu • jméno je totožné se jménem třídy (jediná metoda začínající velkým písmenem) • volání pomocí operátoru new, např. malyObdelnik = new Obdelnik(2,5); • neosahuje návratový typ - nic nevrací, vytváří objekt Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
14/54
Přetěžování konstruktorů Konstruktor je metoda, která vytvoří objekt a nastaví jeho počáteční hodnoty. Budeme chtít 3 typy konstruktorů pro Obdelnik: • bez parametrů - vytvoří obdélník o stranách 0x0, • jeden parametr - vytvoří čtverec, • 2 parametry - šířka x výška
public class Obdelnik { Obdelnik(){ sirka = vyska =0; } Obdelnik(int a){ sirka = vyska = a; } Obdelnik(int s, int v){ }
sirka = s; vyska = v; }
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
15/54
Přetěžování konstruktorů II Budeme chtít konstruktor, který u vytvářeného obdélníku specifikuje jeho barvu. public class Obdelnik { … Obdelnik(int s, int v){
sirka = s;
Stejný kód, správné by bylo použití jednoho místa pro tento kód - jednodušší opravy.
vyska = v; } Obdelnik(int s, int v, Color c){ sirka = s; vyska = v; barva = c; } }
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
16/54
Vzájemné volání konstruktorů Vytvoříme jedem „univerzální“ konstruktor a ostatní jej budou volat public class Obdelnik { …
Obdelnik(int s, int v){
nastavení implicitní hodnoty
this(s,v,Color.BLACK); } volání konstruktoru téže třídy Obdelnik(int s, int v, Color c){ sirka = s; vyska = v; barva = c; } } Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
17/54
Více referencí na jeden objekt, smetí public class ObdelnikTest { public static void main(String[] args) { Obdelnik prvni = new Obdelnik(5,7); Obdelnik druhy = new Obdelnik(5,2); druhy = prvni; System.out.println("Stejne? "+(prvni==druhy)); System.out.println("Stejne?"+ prvni.equals(druhy)); true } true } první
druhý
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
smetí, Paměť přidělená nepřístupným objektům se uvolňuje automaticky (sbírání smetí, garbage collection)
18/54
Třída pro testování obdélníka Není třeba předávat šířku a výšku, public class ObdelnikTest { každá instance (objekt) zná své public static void main(String[] args) { rozměry!! Obdelnik maly; maly = new Obdelnik(1,5); Obdelnik velky = new Obdelnik(10,5); System.out.println("Obvod maleho je "+ maly.vypoctiObvod()); 2*( sirka + vyska ) = 2*( 1 + 5 ) = 12
} } maly velky
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
19/54
Třída versus objekt Třída návrhový vzor, šablona reprezentovaná zápisem v Javě, existuje i mimo program
Obdelnik
Objekt jeden konkrétní výrobek vyrobený podle třídy vytvořen za běhu programu, žije během života programu (lze jej uložit na disk, není reprezentován kódem programu) Obdelnik maly = new Obdelnik(1,5); Obdelnik velky = new Obdelnik(10,5);
Clovek „František Navrátil“ „Julie Capuletová“
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
20/54
Operátor this • •
Každý objekt má implicitní operátor this, který obsahuje odkaz na "svou" instanci Hodnotou operátoru this je odkaz na objekt pro který byla metoda zavolána (implicitní parametr odkazu na objekt) • Umožňuje přístup k vlastním instančním proměnným v instančních metodách public class Bod { double x, y; public Bod(double x, double y) { this.x = x; this.y = y; pocetBodu++; } • Podobně funguje operátor this i pro metody: • pokud je instanční metoda volána z jiné instanční metody té samé třídy, potom se volá pomocí operátoru this (operátor se může vynechat) • ve statické metodě nelze použít this ! • pokud se volá z jiného kontextu, uvádí se před jejím jménem přístup k příslušné instanci (tečka notace) např. předané parametrem
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
21/54
Vlastnosti konstruktorů • • • •
Jméno konstruktoru je totožné se jménem třídy Konstruktor nemá návratovou hodnotu (ani void) Předčasně lze ukončit činnost konstruktoru return bez parametrů Konstruktor má parametrovou část jako metoda - může mít libovolný počet a typ parametrů • V těle konstruktoru použít operátor this, který obsahuje odkaz na právě konstruovaný objekt • Konstruktor je zpravidla vždy public (!) – //třída java.lang.Math jej má private – proč?
• Příslušný konstruktor je volán automaticky při vytváření objektu operátorem new
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
22/54
Třída jako zdroj funkcí •
Třída nemusí obsahovat deklaraci hlavní funkce main; třída bez hlavní funkce main nepředepisuje program, který lze spustit, ale zavádí prostředky, které lze v jiných třídách využít – „knihovnu“ • Příkladem je: • knihovní třída Math poskytující matematické funkce • třída Scanner poskytující jednoduché funkce pro vstup a výstup
•
Poznámka: – Třída s hlavní funkcí main tvořící základ programu je specialitou jazyka Java • v jiných jazycích, např. v C++, lze program vytvořit bez použití třídy
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
23/54
Třída a metoda main • Základem aplikace, tj. uživatelského programu, je třída, ve které • je deklarována spouštěcí metoda přesně takto: public static void main( String[ ] args ) { ... }
Metoda main musí být statická, voláme ji dříve než se vytvoří nějaký objekt Každá třída může obsahovat metodu main, pak se využívá pro: – testování funkčnosti objektu – ukázku použití metod objektu
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
24/54
Statické versus instanční metody •
Třída může definovat dva druhy metod: • statické metody – metody třídy, procedury a funkce • instanční metody – metody objektů
•
Metody obou druhů mohou mít parametry a mohou vracet výsledek nějakého typu • Statická metoda označuje operaci (dílčí algoritmus, řešení dílčího podproblému), jejíž vyvolání (provedení) obsahuje jméno třídy, jméno metody a seznam skutečných parametrů •
jméno_třídy.jméno_metody(seznam skutečných parametrů) (lze využít i volání pomocí referenční prom., ale není doporučeno)
Statickým metodám třídy odpovídají v jiných jazycích procedury (nevracejí žádnou hodnotu) a funkce (vracejí hodnotu nějakého typu) • Instanční metoda označuje operaci nad objektem (instancí (!)) dané třídy, jejíž vyvolání obsahuje referenční proměnnou objektu, jméno metody a seznam skutečných parametrů referenční_proměnná.jméno_metody(seznam skut. parametrů)
• •
Statickým metodám třídy budeme i nadále říkat procedury a funkce Instančním metodám budeme zkráceně říkat metody
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
25/54
Instanční metody I • Operace s objekty se realizují pomocí instančních metod • Metody mohou mít parametry a mohou vracet výsledek • Volání, tj. užití, metody m na objekt referencovaný proměnnou p má tvar: p.m(seznam argumentů)
Zkráceně říkáme, že „metoda m se volá na objekt p“
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
26/54
Instanční metody II •
Příklady metod definovaných třídou Obdelnik pro objekty typu Obdelnik:
• vypoctiObvod • int vypoctiObsah(){ Poznámka:
• String toString() – je metodou každého objektu, nepřekreje-li se, pak jméno třídy + hash kód např. pjv.Obdelnik@1f6a7b9 – výsledkem volání c.toString() je řetězec tvořící znakovou reprezentaci komplexního čísla c (metodou je zavedena implicitní typová konverze z typu Obdelnik na typ String), často se překrývá!
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
27/54
Statické metody public class Obdelnik { int sirka …. static int vratPocetRohu(){ // sirka = 6; //CHYBA,statická metoda nevidí instanční proměnné return 4; 4 } public class ObdelnikTest { 4 } public static void main(String[] args) { Obdelnik maly = new Obdelnik(1,5); System.out.println("Pocet rohu obdelnika je "+Obdelnik.vratPocetRohu()); System.out.println("Maly obdelnik ma "+maly.vratPocetRohu()+ " rohu."); } } Je to možné, ale nelogické!!! Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
28/54
Statické atributy a metody - Math Knihovna matematických funkcí - třída java.lang.Math obsahuje statické proměnné (zde konstanty typu double) PI a E statické metody reprezentující matematické funkce: double x = Math.sin(0,5); • sin, cos, tan, … goniometrické funkce 1 • abs … absolutní hodnota 3 3 • min, max • log … logaritmus • sqrt … odmocnina
a =√a
• pow(double a, double b) … ab • random … vrací náhodné double číslo z intervalu <0;1) • round … zaokrouhlení – vrací double, proč nevrací int?? • a mnohé další Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
29/54
Pořádek Třída ( class ), interfejs ( interface, tj. rozhraní ) a výčet ( což je speciální třída enum ) jsou v Javě základními stavebními kameny. Ukládají se do tzv. balíčků ( package ), přístup k nim se usnadní import. Základním balíčkem je java.lang, bez něho by Java vůbec nefungovala. Zdrojové soubory, tj. kompilační jednotky, mají příponu .java a obsahují: -
Jeden příkaz package - je vždy první. Lze ho sice vynechat – pak se jedná o tzv. noname space – nedoporučuje se. - Několik ( i žádný ) příkazů [ static ] import pro snadnější přístup k jiným balíčkům ( import java.lang.*; je default ). - Definice tříd, interfejsů a výčtů v libovolném pořadí. - Dokumentační komentáře před třídou, interfejsem a jejich složkami. - Ostatní komentáře ( řádkové nebo blokové ) kdekoli. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
30/54
Pořádek
• Ve zdrojovém souboru může být nanejvýš jedna vrcholná (top) třída, výčet či interfejs s modifikátorem public - pak musí být jméno zdrojového souboru shodné se jménem oné třídy, výčtu či interfejsu. • Kompilátor vytvoří tolik souborů bytekódu, kolik je ve zdrojovém tříd, výčtů a interfejsů ( i vnitřních ). Vzniklé soubory mají odpovídající jména s extenzí .class. ( Vnitřní třídy či interfejsy mají vlastní jména složená ze sekvence jmen vnějších tříd či interfejsů oddělených dolarem. ) • Bytekódové soubory jsou přijatelné pro JVM, jen tehdy leží-li v těch adresářích jejichž cesta odpovídá operandu v příkazu package. Tzv. CLASSPATH, musí odkazovat na adresář v němž se nalézá adresář shodného jména s první složkou jména uvedeného v příkazu package.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
32/54
Účel tříd a interfejsů Třídy slouží jako: - Úložiště statického kontextu tj. statických položek tříd. - Plán pro tvorbu objektů obsahující nestatické položky. - Zdroj neprivátních členů pro dědictví potomkům. - Privátní zdroj funkcionality potomků. - Brána pro spuštění aplikace pomocí public static void main( String ... Interfejsy slouží jako norma či požadavek. - Nemají funkcionalitu. - Nemají konstruktory ani inicializátory. - Mohou mít jen abstraktní metody. - Mohou mít jen finální statické atributy. - Mohou být i prázdné – tzv. tagging Interfejsy. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
33/54
Typy • Jménům se v definici přiřadí neměnitelný typ, který může být: - primitivní – primitivních typů je jen 8. - referenční, tj. dle: - dle třídy nebo interfejsu, - pole ( primitivních hodnot anebo referencí ). - void ( prázdný ) - jen jako návratový typ metod.
• Konstruktory nemají vyznačený návratový typ – ten je dán jménem třídy - a musejí být nazvány přesně podle třídy. Java nemá destruktory – ničení objektů zajišťuje garbage collector. (Object má protected void finalize() throws Throwable {}, nutné přepsat, volá GC při rušení objektu – pro uvolňování vázaných zdrojů, lépe použít finally v try – catch bloku) Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
34/54
Jména • Všechny položky programu musejí být rozlišitelné různými jmény. V některých případech se rozlišují položky shodných jmen dle principu "košile-kabát". • Třídy a interfejsy jsou rozlišitelné pomocí úplných jmen. Ta jsou dána prefixem dle příkazu package a jejich vlastním jménem. • Atributy přejímají úplná jména tříd či interfejsů jako prefix vlastních jmen. • Metody a konstruktory přejímají úplná jména tříd či interfejsů jako prefix vlastních signatur. Signatura metod i konstruktorů se skládá z jejich vlastních jmen a sekvenci typů jejich parametrů. • Metody i konstruktory v téže třídě mohou mít shodná vlastní jména, avšak různé signatury - pak jsou tzv. přetížené (overload). To je vhodné tehdy, mají-li obdobnou funkcionalitu.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
35/54
Abstrakce a konkretizace • Abstrakce je důležitým pohledem na oba světy: ten reálný i ten virtuální, je základem taxonomie složitých systémů. • Abstrakce má tvar stromu: směrem ke kořeni abstrahujeme (vypouštíme detaily), směrem k listům konkretizujeme (přidáváme a realizujeme detaily). • Pomocí abstrakce lze vytvářet velmi užitečné neúplné popisy a plány. Jednak vyjasňují strukturu systému a jednak po pozdějším doplnění se stanou úplnými a tedy konkrétními. • Jen podle konkrétních plánů (tříd) lze vytvářet výrobky (objekty). • Konkrétní třída může zabránit konstrukci objektů privatizací všech svých konstruktorů modifikátorem private a případně ani nepřipustí jejich použití jiným způsobem. (Např. java.lang.Math.) Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
36/54
Abstraktní třídy, metody a interfejsy • Abstraktní třída má modifikátor abstract - konkrétní třída nikoli. Má alespoň jeden konstruktor, nelze však podle ní objekty vytvářet. Nemusí mít žádnou abstraktní metodu. Abstraktní třída nemůže být finální. • Statický kontext ( tj. static atributy, metody, inicializátory, výčty ) abstraktní třídy je funkční. • Abstraktní metoda má v definici místo těla jen středník, např.: public abstract int compareTo( Object s ) ; • Má-li třída abstraktní metodu ( vlastní definovanou či zděděnou a nepřepsanou na konkrétní ), pak musí být označena jako abstraktní. • Interfejs lze považovat za značně omezenou abstraktní třídu, která má všechny metody abstraktní ( netřeba u nich uvádět modifikátor abstract ). Interfejs umožňuje jednak částečný pohled na třídu a jednak slouží s výhodou jako norma či požadavek. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
37/54
Abstrakce, dědičnost a polymorfismus P
Object Object U
E
F
D
G Typy:
Q
A A
R R
B
S
T
C - konkrétní plán
Abstrakce ( po šipkách ) - úží pohled
- abstraktní plán
Vztahy:
- norma, předpis, požadavek Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
extends
implements
(rozšiřuje)
(splňuje) 38/54
Polymorfismus Polymorfismus se týká jen překrytých nestatických metod - umožňují objektům různým podtypům daného nadtypu specifické chování. Polymorfismus je relace ( reflexivní, asymetrická a transitivní ) mezi referenčním typem a množinou referenčních typů, které lze oním typem referovat. Existuje-li dráha ( po kterýchkoli šipkách ) z typu x k typu y pak: • Typ y je abstrakcí typu x, označme: y x • Typ x lze referovat typem y – čili lze říci, že x je také y. • Množina typů Y = { x U y | y x } je polymorfismem typu y. Tři příklady polymorfismu z předchozího obrázku: A = { A, B, C, D }, Q = { Q, B, C, R, S, T }, U = { U, F, G } Zda objekt o patří do určitého typu lze otestovat výrazem: o instanceof Typ má hodnotu true nebo false, přičemž o instanceof Object má vždy hodnotu true . Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
39/54
Dědičnost ( inheritance ) • Dědičnost velmi usnadňuje:
– - Přístup k existujícím třídám a interfejsům a jejich pochopení. - Vytváření nových tříd a interfejsů s využitím vlastností a schopností - již existujících, ověřených a dokumentovaných.
• Všechny třídy ( bez ohledu na balíčky ) tvoří jediný, dědičný, kořenový strom orientovaný směrem ke kořeni, kterým je třída java.lang.Object. Tedy každá třída, kromě java.lang.Object, má právě jednoho přímého předka ( superclass = nadtřída ), jehož je přímým potomkem ( subclass = podtřída ). Svoji přímou nadtřídu vyznačuje podtřída ve své hlavičce za klíčovým slovem extends, jinak je přímým předkem java.lang.Object. • Konkrétní třída java.lang.Object nemá žádného předka ( je to jakoby prapředek Adam ) a tedy nic nezdědila avšak definuje 11 „generálních“ metod. Všechny ostatní třídy jsou tedy jejími přímými či nepřímými potomky a zaručeně mají tyto „generální“ metody. • Třída také dědí od interfejsů uvedených v seznamu za klíčovým slovem implements. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
40/54
Dědičnost ( inheritance ) • Interfejsy tvoří nesouvislý acyklický graf. ( Hrany jsou jen typu extends. ) • Není žádný základní interfejs ( co obdoba třídy java.lang.Object ) • Interfejs: – nemusí mít žádného předka, – může být přímým potomkem více interfejsů uvedených v seznam za klíčovým slovem extends, – nemůže být potomkem žádné třídy, – nemůže být finální.
Dědí se pouze viditelné členy ( tj. atributy, metody, vnitřní třídy, vnitřní interfejsy, výčty ), jež nemají příliš restriktivní přístupový modifikátor: ( public – protected – default=friend – private tj. vždy – v balíčku či potomek v jiném balíčku – v témže balíčku – nikdy ). Potomek nemůže dědictví odmítnout a tedy není nikdy chudší než předek – zpravidla bývá mnohem bohatší. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
41/54
Dědičnost metod
Interfejsy obsahují jen nestatické abstraktní metody
generální metody:
java.lang.
clone(), equals(), hashCode(),
Object Object U
finalize(), getClass(), notify(),
a statické finální atributy
P
m2( );
notifyAll(), toString(), wait(...)
abstract
E
static m6( ){...}
A A
Q
m1( ){...}
m3( );
abstract
F
D
static private m7( ){...};
B B
m3( ){...} m4( ){...}
R
S
m4( );
m4( ); m5( );
m6( ){...}
abstract
G třída
m2( ){...} m3( ){...} m5( ){...}
static m6( ){...}
finální třída
abstr. třída
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
T
C C interfejs
extends
implements 42/54
Dědičnost atributů
Interfejsy obsahují jen nestatické abstraktní metody
java.lang.
Object Object U
a statické finální atributy i=1
P Atributy mohou být libovolně [ne]statické
E
final n=4
A A
Q
private
j=2
m=5
F
G třída
n=44
D
B B
C C
n=44
finální třída
abstr. třída
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
i=11 j=22 valid k=3
i=1/11 ? j=22 k=3/33 ?
interfejs
R
i=1 j=22 k=3
T extends
S
i=1 j=2 k=3
i=1 j=2/22 ? invalid k=33
implements 43/54
Syntaxe třídy [ public | protected | private ] [ abstract | final ] [ strictfp ] static class JménoTřídy [ <~> ] // hlavička třídy [ extends JménoNadTřídy [ <~> ] | extends java.lang.Object ] [ implements JménoInterfejsu [ <~> ] , ... ] { // tělo třídy .... // atributy statické a nestatické .... // inicializátory statické a nestatické .... // konstruktory .... // metody statické a nestatické - pro vnořené (nested) .... // vnořené a vnitřní třídy - typové parametry .... // výčty enum - meta symboly .... // vnořené interfejsy …. // anotace } Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
44/54
Syntaxe interfejsu
[ public | protected | private ] [ strictfp ] [ static ] [ abstract ] interface JménoInterfejsu [ <~> ] // hlavička interfejsu [ extends JménoNadInterfejsu [ <~> ] , ... ] { // tělo interfejsu // [ public static final ] atributy inicializované již v definici // [ public abstract ] metody ale ne static final strictfp native // vnořené a vnitřní třídy // výčty enum // vnořené interfejsy // anotace - jen pro vnořené (nested) } - typové parametry - typové parametry • Metody stejných signatur kolidují jen při nekompatibilitě návratových typů. • Interfejs označený public, má atributy také public - což netřeba uvádět. • Při vícečetném dědění stejnojmenných atributů nastane kolize. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
45/54
Syntaxe anonymní třídy
Anonymní třída nemá hlavičku třídy, tudíž ani jméno, nemůže mít potomka a slouží k vytvoření jediného objektu. Má však jediného přímého předka tím může být nejen buď nefinální třída, anebo interfejs a pak je nadtřídou java.lang.Object. •
TypT t = new Třída ( ... ) { // tělo anonymní třídy .... // nestatické atributy, inicializátory, metody a třídy } TypT může být Třída anebo její nadtypy.
•
TypZ z = new Interfejs ( ) { // tělo anonymní třídy .... // nestatické atributy, inicializátory, metody a třídy } TypZ může být Interfejs nebo jeho nadinterfejsy anebo Object.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
46/54
Dědictví tříd • V nově definované třídě lze: - zdědit od nadtřídy jen nestatické členy, které jsou public či protected a patří-li potomek do stejného balíčku, pak i default “friend” členy. Privátní členy se nedědí. - přidat nové členy. - přepsat zděděné metody novými metodami ( override ), nelze však přepsat statickou nestatickou a naopak. - zastínit zděděné atributy stejnojmennými novými atributy ( shadow ), - definovat vlastní konstruktory a inicializátory. Zdědění abstraktních metod, není " výhodné dědictví ", leč břemeno, se kterým se může třída vyrovnat jedním z těchto způsobů: - přepsat všechny zděděné abstraktní metody na konkrétní, - ponechat některé abstraktní - a bude tudíž abstraktní třídou. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
47/54
Dědictví interfejsu • Při dědění metod nemůže dojít ke kolizi, neboť všechny jsou abstraktní, tj. nemají tělo – místo něho mají středník. • Při dědění stejnojmenných atributů od více předků-interfejsů dojde k víceznačnosti a to i když jsou inicializovány na stejnou hodnotu. Ke kolizi dojde i při dědění do třídy stejnojmenných atributů z nadtřídy a z interfejsu či jen z více interfejsů. Dědictví z interfejsů do třídy se neuplatní tehdy, je-li ve třídě jméno atributu definováno ( ne zděděno ). Může záležet i na pořadí v jakém jsou interfejsy uvedeny v implements.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
48/54
Zastínění a překrytí • Zděděný atribut, lze v potomkovi zastínit stejnojmenným atributem, přičemž na typech a modifikátorech přístupu nezáleží. Nefinální statickou metodu lze zastínit. Statické atributy a metody jsou přístupné přes jméno třídy. • Překrytí metod ve třídě Nevyhovuje-li potomkovi zděděná nefinální metoda, lze v potomkovi deklarovat metodu, která: – – –
má shodnou signaturu, má kovariantní návratový typ, typ či subtyp – avšak ne primitivní, nemění statičnost – nestatičnost, nezužuje modifikátor přístupu, nerozšiřuje množinu kontrolovaných výjimek udaných za throws. Překrytím metody v potomkovi se metoda v předkovi nezmění. Přepsaná nestatická metoda je přístupná z přímého potomka pomocí klíčového slova super. Statická metoda je přístupná přes jméno třídy.
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
49/54
Dědění versus kompozice Vytvářet bohatší třídy lze: • Děděním tj. přidáváním zejména metod, např.: class B extends A { void m1( ... ) { ... } void m2( ... ) { ... } }
// relace: B is A
• Kompozicí tj. přidávání zejména referenčních atributů class C { B b = new B( ... ); C c = new C( ... ); } class B { void m1( ... ) { ... } void m2( ... ) { ... } }
// relace: C has B and C
Doporučuje se dávat přednost kompozici, dědění používat obezřetně. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
50/54
Zapouzdření ( encapsulation ) • Ve třídách a objektech lze ukrýt atributy, metody, konstruktory, vnitřní třídy a vnitřní interfejsy a tím podpořit spořádanost a bezpečnost. • Inicializátory jsou skryté již tím, že nemají jméno. • Míru zapouzdření určuje modifikátor viditelnosti členu či konstruktoru. modifikátor viditelnost public - odevšad protected - ve vlastním balíčku a v potomcích v jiných balíčcích - modifikátor se nepíše, chápe se jako package private tj. viditelný ve vlastním balíčku ( “friend” v C/C++ ) private - jen ve vlastní třídě ( a i z vnitřních tříd ) • K nedostupným členům nějaké třídy lze přistupovat z jiné třídy jen pomocí neprivátních metod oné třídy. • V interfejsech lze zapouzdřovat jen atributy a jen úrovní “default”. Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
51/54
Getry a setry
Dobrovolná jmenná konvence pro přístupové metody k zejména privátním atributům, které jejich hodnotu vydávají ( tzv. getter, accessor ) anebo mění ( tzv. setter, mutator ) usnadňuje tvorbu nadstavbového softwaru. Tento způsob je podmínkou pro tvorbu tzv. Java beans. • private int cenaKusu = … ; // atribut public int getCenaKusu( ) { return cenaKusu; } // getter public void setCenaKusu ( int cenaKusu ) { // setter .... this.cenaKusu = cenaKusu; } private Point vrcholHory = … ; // atribut public Point getVrcholHory ( ) { return vrcholHory ; } // getter public void setVrcholHory ( Point vrcholHory ) { // setter .... this.vrcholHory = vrcholHory ; } Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
52/54
Getry a setry Getry vracející boolean často začínají “is” resp. “has” – např.: isVisible( ) resp. hasNext( ).
Pro jednorozměrná pole se používají getry a setry např. takto: private String[ ] line = { "A" , "B" , "C" } ; public String getLine( int index ) { return line[ index ] ; } public void setLine( int index, String line ) { … this.line[ index ] = line ; }
Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
53/54
Inicializace statických atributů Když JVM zavede třídu či interfejs do paměti, inicializuje jejich statické atributy. U tříd i tzv. statickými inicializátory - ty připomínají metody bez hlavičky, mají přístup jen ke statickému kontextu, nic nevracejí, nemají signaturu, nevyznačují vyhazování výjimek a provádějí se jen jednou a to v pořadí zápisu. Nelze je volat, nejsou členy třídy a nedědí se. Syntakticky jsou velmi prosté: static { ... } class Priklad { static int j = 10, k, n; static { String value1 = System.getProperty( "key1" ) ; n = Integer.parse( value1 ) ; k = Integer.parseInt( System.getProperty( "key2" ) ) ; } static Color[ ] c = new Color[ n ] ; static { for ( int i = 0; i < c.length; i++ ) c[ i ] = new Color( i, i*j, 0 ); } } // Execute as: java -Dkey1=value1 -Dkey2=value2 MyProgram Ing. Miroslav Balík, Ph.D. - BI-PJV- 02
54/54