4. ZÁKLADNÍ POJMY Z OBJEKTOVĚ ORIENTOVANÉHO PROGRAMOVÁNÍ

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

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

Seminář Java II p.1/43

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

typová konverze typová inference

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

Úvod do programovacích jazyků (Java)

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

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

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

8 Třídy, objekty, metody, předávání argumentů metod

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

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

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Z. Kotala, P. Toman: Java ( Obsah )

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

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Generické programování

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

Teoretické minimum z PJV

Abstraktní třída a rozhraní

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

Základy objektové orientace I. Únor 2010

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

Výčtový typ strana 67

Java Enum Java, zimní semestr ,2017 1

Algoritmizace a programování

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

Více o konstruktorech a destruktorech

Programování v Javě I. Leden 2008

PREPROCESOR POKRAČOVÁNÍ

1. Programování proti rozhraní

Objekty v PHP 5.x. This is an object-oriented system. If we change anything, the users object.

Principy objektově orientovaného programování

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

Seminář Java IV p.1/38

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

Konstruktory a destruktory

11 Diagram tříd, asociace, dědičnost, abstraktní třídy

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

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

Virtuální metody - polymorfizmus

Vytváření a použití knihoven tříd

Zápis programu v jazyce C#

Dědění, polymorfismus

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

Programové konvence, dokumentace a ladění. Programování II 2. přednáška Alena Buchalcevová

přetížení operátorů (o)

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

1. Dědičnost a polymorfismus

7. Datové typy v Javě

Abstraktní datové typy: zásobník

Obsah. Úvod 11 Základy programování 11 Objektový přístup 11 Procvičování 11 Zvláštní odstavce 12 Zpětná vazba od čtenářů 12 Errata 13

Java Výjimky Java, zimní semestr

Paměť počítače. alg2 1

20. Projekt Domácí mediotéka

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

IRAE 07/08 Přednáška č. 1

Obsah přednášky. Postup při vytváření objektů. Postup při vytváření objektů. Alokace paměti. Inicializace hodnot atributů

Objekty strana 11. Abstrakce je základní objektovou vlastností. Skutečnost, kterou chceme do programu promítnout,

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

Osnova přednášky. Programové prostředky řízení Úvod do C# II. Přístup ke členům. Členy (Members)

Proměnné a datové typy

Úvod do programovacích jazyků (Java)

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

Jazyk C# (seminář 6)

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

NMIN201 Objektově orientované programování 1 / :36:09

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

PROGRAMOVÁNÍ V C++ CVIČENÍ

Programovací jazyk Java

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

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

O autorovi O odborném korektorovi Úvod 17 Vývoj jazyka Java Java SE 8 Struktura této knihy Předchozí zkušenosti s programováním nejsou potřebné

Objektově orientované programování

Vaše jistota na trhu IT. Balíčky. Rudolf Pecinovský

NPRG031 Programování II 1 / :25:46

Ukazka knihy z internetoveho knihkupectvi

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

"Václav Klaus". public class Clovek { protected String jmeno; protected int roknarozeni; public Clovek(String j, int rn) {

ZÁPADOČESKÁ UNIVERZITA V PLZNI

Algoritmizace a programování

Java a XML. 10/26/09 1/7 Java a XML

Zpracování deklarací a přidělování paměti

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

JAVA. Krátke poznámky:

UJO Framework. revoluční architektura beans. verze

Programování II. Návrh programu I 2018/19

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

RMI Remote Method Invocation

Úvod do programování - Java. Cvičení č.4

1. ÚVOD ZÁKLADY JAZYKA...

Dědičnost (inheritance)

Jazyk C# (seminář 3)

Úvod do programovacích jazyků (Java)

Transkript:

4. ZÁKLADNÍ POJMY Z OBJEKTOVĚ ORIENTOVANÉHO PROGRAMOVÁNÍ OBJEKT Program v Javě je staticky strukturován na třídy, jejichž instance (objekty) za běhu dynamicky programu vznikají a zanikají. Objekt je nejprve vytvořen (instanciován), následně může být používán a nakonec je zrušen. VYTVOŘENÍ OBJEKTU K vytvoření objektu slouží operátor new, jehož základní syntaxe: new voláníkonstruktoru Operátor alokuje paměť pro objekt a zavolá konstruktor, což je speciální metoda, která provádí inicializaci objektu. Jméno konstruktoru je vždy shodné se jménem třídy objektu. new String("ahoj"); vytvoří objekt třídy String a inicializuje ho konstruktorem s parametrem "ahoj". Operátor new vrací referenci, odkazující na vytvořený objekt. Tato reference se při vytvoření objektu obvykle zároveň ukládá do referenční proměnné. String retezec; retezec = new String("ahoj"); // deklarace proměnné // přiřazení reference nebo zkráceně: String retezec = new String("ahoj"); POUŽÍVÁNÍ OBJEKTU Používání objektu spočívá ve volání metod a přímé manipulaci se členskými proměnnými. Pro přístup k proměnné nebo metodě se používá tečková notace: Příklad reference.jménoproměnné reference.volánímetody String retezec = new String("ahoj"); retezec = retezec.concat("!"); // vytvoření objektu // volání metody

ZRUŠENÍ OBJEKTU Java neumožňuje přímé rušení (dealokaci) objektu. Objekt je zrušen automaticky až tehdy, neexistuje-li na něj reference. Jsou například rušeny všechny objekty lokálních proměnných při ukončení metody. "Ruční" zneplatnění reference se provede přiřazením hodnoty null příslušné referenční proměnné. TŘÍDA Pro každý objekt musí být před jeho vytvořením deklarována třída, ať už navržená v programu nebo knihovní. Knihovní třídy jsou uloženy v balících. DEKLARACE TŘÍDY Nejjednodušší deklarace třídy má syntaxi: class JménoTřídy { // tělo třídy Identifikátor JménoTřídy slouží jako objektový typ, například v deklaraci referenční proměnné. V těle třídy mezi složenými závorkami mohou být deklarace členských proměnných a/nebo deklarace a definice metod - obvykle v tomto pořadí, ale není to vyžadováno. Všimněte si, že za uzavírající závorkou deklarace třídy není středník. Obecná deklarace třídy vypadá takto: [ modifikátory ] class jménotřídy [ extends jménorodičovskétřídy ] [ implements seznamrozhraní ] { // tělo třídy modifikátory mohou být následující: public - označuje veřejnou třídu. Veřejná třída je přístupná i mimo balík, kde je deklarována. Není-li třída veřejná, je přístupná pouze ve svém balíku. abstract - třída deklarovaná s tímto modifikátorem je abstraktní a nesmí být nikdy instanciována. Nejsou-li uvedeny příslušné modifikátory, je třída implicitně pokládána za neveřejnou, neabstraktní a ne-koncovou. Zároveň nelze použít modifikátory abstract a final.

Za jménem třídy může být specifikována rodičovská třída pomocí klíčového slova extends(angl. rozšiřuje). Třída dědí proměnné a metody třídy rodičovské. Za klíčovým slovem implements následuje jedno nebo více jmen rozhraní, které třída implementuje. To mimo jiné znamená, že třída musí obsahovat definice metod uvedené v příslušném rozhraní. Je-li jmen rozhraní více, jsou oddělena čárkami. METODY Nejjednodušší definice metody má tvar: NávratovýTyp jménometody ( parametry ) { // tělo metody NávratovýTyp musí být datový typ. Návrat z metody a případné předání návratové hodnoty způsobí příkaz return. Je-li návratovým typem void, metoda nevrací hodnotu. jménometody musí být platný identifikátor. Pokud mají v jedné třídě dvě metody shodná jména, musí mít odlišný počet a/nebo typ parametrů - tzv. přetěžování metod (overloading). Při volání přetížené metody překladač na základě typů argumentů rozhodne, kterou volat. Díky přetěžování nemusí existovat různě pojmenované metody, jejichž funkce je prakticky shodná. Argumentem metody System.out.println(), která provádí výpis na standardní výstup, může být proměnná kteréhokoliv základního datového typu nebo nic. System.out.println(); // odřádkuje System.out.println("ahoj"); // vypíše ahoj (1) System.out.println(12345); // vypíše 12345 (2) Ve všech případech se jedná o volání jiné přetížené metody - překladač se rozhoduje na základě argumentů - první případ se liší počtem argumentů, druhé dva jejich typem: (1) předává řetězec, (2) celé číslo. Na pořadí definic metod nezáleží - dopředné reference překladač zpracovává automaticky. Formální parametry metody: Nejsou-li parametry uvedeny, jde o metodu bez parametrů. Každý parametr má tvar: [final] typ jménoparametru

Modifikátor final, který lze použít až od JDK1.1, značí konstantní hodnotu (nelze měnit hodnotu argumentu v metodě). V těle metody nelze deklarovat lokální proměnnou pojmenovanou stejně jako parametr. Je-li parametrů více, jsou odděleny čárkami Je-li jméno parametru stejné jako jméno členské proměnné, dochází k jejímu zastínění (hiding) parametrem. K explicitnímu přístupu ke členské proměnné pak slouží operátor this, který vrací referenci objektu na sebe class Trida { int x; Trida (int x) { // zastínění členské proměnné x parametrem this.x = x; // přiřazení hodnoty parametru členské proměnné x Obecná deklarace metody vypadá takto: [ práva ] [static] [abstract] [final] [native] [synchronized] NávratovýTyp jménometody ( parametry ) [throws seznamvýjimek ] práva - tato položka určuje přístupnost metody vně třídy a pravidla pro dědičnost. Metoda může být buď veřejná (public), chráněná (protected), soukromá (private) nebo nemusí mít práva specifikována vůbec. static - označuje statickou metodu. Statické metody je možné narozdíl od nestatických volat i tehdy, neexistuje-li žádná instance dané třídy. Mohou však přímo manipulovat pouze se statickými (a svými lokálními) proměnnými. Volání statické metody má tvar: [ JménoTřídy. ] jménometody ( parametry ); JménoTřídy se nemusí specifikovat uvnitř třídy, která statickou metodu definuje. V jedné třídě nemůže být definována shodně pojmenovaná statická i nestatická metoda se stejným počtem a typem parametrů - jinak dojde k chybě při překladu. abstract - metody deklarované jako abstraktní nemají v dané třídě tělo a musí být definovány až potomky třídy. Třída, která obsahuje abstraktní metody, nemůže být instanciována a musí být rovněž deklarována jako abstraktní. synchronized final - označuje koncovou metodu. Koncová metoda nesmí být potomky překryta. native - nativní metody umožňují sloučit programy psané v Javě a jiných jazycích. Například většina nízkoúrovňových metod z Java Core API je nativních. V běžných

aplikacích se nativní metody nepoužívají kvůli jejich nepřenositelosti. V appletech se používat nesmí. Klíčové slovo throws uvozuje jedno nebo více jmen tříd výjimek, které může metoda vyvolat. Je-li výjimek více jsou odděleny čárkami. KONSTRUKTORY Konstruktor je speciální metoda, která se volá pouze při vytváření objektu a slouží k jeho inicializaci. Jméno konstruktoru musí být shodné se jménem třídy, v níž je definován. Návratový typ konstruktoru se neuvádí. Pro konstruktory platí pravidla uvedená pro metody. Jejich deklarace však nesmí obsahovat modifikátory abstract, final, native, static a synchronized a nedochází k dědění konstruktorů. class Bod { Bod() { // konstrukor třídy Bod Každá třída má alespoň jeden konstruktor. Pokud ve třídě konstruktor není uveden, vytvoří překladač automaticky implicitní konstruktor bez parametrů (default constructor), který nic neprovádí. Konstruktor každé třídy musí na začátku obsahovat volání konstruktoru rodičovské třídy, aby se zajistila řádná inicializace zděděných proměnných (tzv. řetězení konstruktorů). K volání rodičovského konstruktoru slouží klíčové slovo super. super( parametrykonstruktoru ); Toto volání musí být provedeno jako první, aby se zajistila řádná inicializace v rodičovské třídě. Volání rodičovského konstruktoru lze vynechat pouze v případě, že rodičovská třída má pouze jeden konstruktor bez parametrů nebo konstruktor implicitní - pak toto volání překladač na začátek konstruktoru sám doplní. Volání konstruktoru téže třídy se provádí pomocí operátoru this. Volat konstruktor však lze opět pouze z konstruktoru a toto volání musí být provedeno jako první. ČLENSKÉ PROMĚNNÉ Členské proměnné se deklarují v těle třídy - mimo těla metod (jinak by se jednalo o lokální proměnné). Podle konvence se deklarace členských proměnných uvádějí před deklaracemi metod.

Pro členské proměnné platí podobná pravidla jako pro lokální proměnné. Jejich deklarace může navíc obsahovat následující modifikátory: [ práva ] [static] [transient] [final] [volatile] typ jménoproměnné Pokud není členská proměnná v deklaraci inicializována, je jí přiřazena implicitní hodnota: nula - pro celočíselné a racionální typy, \u0000 - pro typ char, false - pro logický typ, null - pro referenční typy (neplatná reference). práva - tato položka určuje přístupnost proměnné vně třídy a pravidla pro dědičnost. Proměnná může být buď veřejná (public), chráněná (protected) nebo soukromá (private) nebo nemusí mít práva specifikována vůbec. static - statická proměnná existuje jen v jednom exempláři, který všechny objekty dané třídy (včetně potomků) sdílí, tj. při vytváření instance třídy není pro statickou proměnnou znovu alokována paměť. Statické proměnné jsou přístupné (v souladu s přístupovými právy) i tehdy, neexistuje-li (ještě) instance třídy. Ke statické proměnné se přistupuje touto konstrukcí: JménoTřídy.jménoProměnné transient - informuje, že proměnná není součástí perzistentního stavu objektu - systém nebude její hodnotu uchovávat při zasílání objektu po síti apod. volatile - zaručí, že obsah proměnné bude aktualizován při každém jejím použití (čtení, přiřazení) - používá se tehdy, přistupuje-li se v programu k proměnné asynchronně a při každém čtení proměnné je třeba získat aktuální hodnotu. Java zaručuje, že hodnota libovolné proměnné je konzistentní s výjimkou typů long a double, které by měly být vždy deklarovány s modifikátorem volatile, je-li k nim prováděn asynchronní přístup. final - označuje konstantu. Její obsah je nutno inicializovat při deklaraci a nesmí se v programu měnit (překladač ohlásí chybu). DĚDIČNOST Třída-potomek se od rodičovské třídy odvodí v deklaraci pomocí klíčového slova extends. Potomek od přímého rodiče dědí, tj. přejímá jako by byly znovu definovány, všechny členské proměnné a metody, které: jsou deklarovány jako veřejné (public) nebo chráněné (protected), nemají explicitně určena přístupová práva a zároveň se rodičovská třída nachází ve stejném balíku jako potomek.

Potomek nedědí členské proměnné a metody, které: jsou deklarovány jako soukromé (private), jsou deklarovány v jiném balíku a nejsou veřejné (public), mají v potomkovi stejné jméno (a typy parametrů - u metod) jako v rodičovské třídě. Tyto členské proměnné (metody) jsou předefinovány - hovoří se o zastínění proměnných a překrytí metod. Při překrývání metod je možné přístupová práva pouze rozšířit (na public nebo protected - v případě implicitních práv). Naopak seznam (resp. typy) výjimek deklarovaných pomocí throws lze pouze zúžit. Na změny modifikátorů a členské proměnné omezení kladena nejsou. K překrytým metodám a zastíněným proměnným rodiče se přistupuje pomocí operátoru super, který vrací referenci na rodičovskou třídu: super. jménočlensképroměnné super. jménometody class A { void a() throws Exception { class B extends A { void a() { // zúžení seznamu výjimek try { super.a(); // volání metody rodiče: A.a a(); // volání sama sebe catch (Exception e) { PŘÍSTUPOVÁ PRÁVA Členské proměnné a metody mají specifikována přístupová práva určující okruh tříd, které k nim mají přístup. Přístupem se rozumí možnost přímé manipulace se členskými proměnným a volání metod. Třída má přístup pouze k metodám a členským proměnným, které: sama deklaruje, dědí,

jsou deklarovány jako public v jiných veřejných třídách, jsou umístěny ve třídě téhož balíku a zároveň mají přístup nespecifikován nebo nastaven jako public či protected. Třída nemá přístup ke členským proměnným a metodám z jiných balíků, které jsou soukromé, chráněné nebo mají nespecifikován přístup a dále ke třídám z jiných balíků, které nejsou deklarovány jako veřejné. TŘÍDA OBJECT Třída Object z balíku java.lang je kořenovou třídou ve stromu tříd, tj. všechny třídy, ať už knihovní nebo navržené programátorem, mají společného (nepřímého) rodiče třídu Object. Object definuje základní metody, které musí mít každý objekt v Javě - většinu z nich používá runtime systém. Jedná se o metody: protected native clone() - vytvoří identický objekt (ale nevolá konstruktor) a přiřadí stejné hodnoty všem členským proměnným. Funguje pouze u tříd, které implementují rozhraní Cloneable. public boolean equals(object obj) - porovnává objekt s objektem obj (způsob porovnávání se pro jedntlivé potomky liší). public final Class getclass() - vrací objekt reprezentující třídu instance v runtime systému. protected void finalize() throws Throwable - je volána při úklidu; standardně neprovádí nic. public int hashcode() - používá se k hašování, není-li překrytá vrací totéž co metoda System.identityHashCode(). public String tostring() - vrací identifikační řetězec objektu (často předefinovávaná metoda pro účely ladění). wait(), notify(), notifyall(). ROZHRANÍ (INTERFACE) Rozhraní (interface) je syntaktická struktura obsahující deklarace konstant a metod (bez implementací). Deklarace rozhraní je podobná deklaraci třídy: [public] interface jménorozhraní [ extends seznamrozhraní ] { // tělo rozhraní

public - označuje veřejné rozhraní. Veřejné rozhraní je přístupné i mimo balík, kde je deklarováno. Není-li rozhraní veřejné, je přístupné pouze ve svém balíku. V nepovinné části za klíčovým slovem extends (angl. rozšiřuje) následuje jedno nebo více jmen rozhraní, jejichž konstanty a metody toto rozhraní dědí. Děděné deklarace konstant a metod z více rodičovských rozhraní nesmí kolidovat, podobně jako je tomu u deklarací v rámci jedné třídy. Tělo rozhraní smí obsahovat pouze deklarace konstant a metod. Při tom platí následující pravidla: Všechny metody a konstanty uvedené v deklaraci rozhraní jsou automaticky veřejné (public) a nesmí mít specifikována přístupová práva protected ani private. Všechny metody jsou navíc automaticky abstraktní. I když u proměnné není modifikátor final, jedná se vždy o konstantu. V rozhraní nesmí být použity modifikátory: transient, volatile a synchronized. Rozhraní se používají k zachycení společných prvků tříd, které spolu nemusí souviset ve stromu dědičnosti - společnými prvky jsou konstanty a metody deklarované rozhraním. Třída, která implementuje dané rozhraní, musí obsahovat definice všech(!) metod tohoto rozhraní. Rozhraní pak lze použít jako objektový typ třídy. Program bude obsahovat schránku (clipboard), přes kterou lze kopírovat, a vkládat objekty (text, obrázky, zvuky). Všechny objekty, které lze do schránky umístit, musí kopírování samy umožňovat - musí obsahovat metodu copy(). Z hlediska návrhu není vhodné, aby třídy takto rozdílných objektů měly společného rodiče - třídu, deklarující metodu copy(), kterou všechny povinně zdědí. Výhodnější je deklarovat rozhraní (Clip) obsahující metodu copy(), které budou jednotlivé třídy implementovat - i v tomto případě bude zaručena podpora kopírování ze strany objektů. public interface Clip { byte[] copy(); Metoda copy() bude vracet pole bytů reprezentující objekt ve schránce. Každá třída, jejíž instance lze kopírovat přes schránku, musí implementovat rozhraní Clip. Její deklarace bude: class Obrazek implements Clip {

byte[] copy() { Schránka pak může obsahovat libovolný objekt typu Clip: class Schranka { byte[] schranka; // metoda pro vložení (kopírovatelného) objektu public void vlozit(clip objekt) { rozhraní schranka = objekt.copy(); schránky // typ parametru je // vložení objektu do INICIALIZACE TŘÍD A ROZHRANÍ K inicializaci třídy nebo rozhraní dochází při prvním aktivním použití, které nastane, je-li splněna aspoň jedna z podmínek : je vyvolána metoda nebo konstruktor deklarovaný danou třídou. je vytvořeno pole s prvky typu dané třídy, je proveden přístup k nekonstantní členské proměnné třídy nebo konstantě rozhraní, je proveden přístup ke členské proměnné třídy s modifikátorem final nebo static, která je inicializována hodnotou vypočítanou za běhu programu. Inicializace třídy se skládá z inicializace statických členských proměnných a vykonání statických inicializátorů (viz dále), přičemž před tím musí být inicializována nejprve její rodičovská třída. Inicializace rozhraní spočívá pouze v inicializaci v něm definovaných konstant, nedochází automaticky k inicializaci rodičovského rozhraní.