Objektumorientált programozás Java-ban



Hasonló dokumentumok
és az instanceof operátor

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Programozás I. 5. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

OOP: Java 8.Gy: Abstract osztályok, interfészek

Programozási nyelvek Java

Interfészek. PPT 2007/2008 tavasz.

Java programozási nyelv 5. rész Osztályok III.

Abstract osztályok és interface-ek. 7-dik gyakorlat

JAVA PROGRAMOZÁS 2.ELŐADÁS

Már megismert fogalmak áttekintése

Osztályok. 4. gyakorlat

Osztálytervezés és implementációs ajánlások

Osztálytervezés és implementációs ajánlások

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Osztályok. construct () destruct() $b=new Book(); $b=null; unset ($b); book.php: <?php class Book { private $isbn; public $title;

Programozási nyelvek II.: JAVA

Programozási nyelvek Java

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 2.ELŐADÁS. Objektumorientált programozás

Vé V g é r g e r h e a h j a tá t s á i s s z s ál á ak a Runnable, Thread

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

Alkalmazott Modul III 6. előadás. Objektumorientált programozás: öröklődés és polimorfizmus

Programozás módszertan p.1/46

Java programozási nyelv 4. rész Osztályok II.

Visual C++ osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés.

Se S r e ial a iza z t a ion o n (in n Ja J v a a v ) a Szerializáció

Objektumorientált programozás C# nyelven

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

III. OOP (objektumok, osztályok)

OOP #14 (referencia-elv)

Programozási nyelvek Java

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

UML (Unified Modelling Language)

ZH mintapélda. Feladat. Felület

Programozás I. Első ZH segédlet

Osztályok, objektumok

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

Helyes-e az alábbi kódrészlet? int i = 1; i = i * 3 + 1; int j; j = i + 1; Nem. Igen. Hányféleképpen lehet Javaban megjegyzést írni?

Interfészek. Programozás II. előadás. Szénási Sándor.

Programozási nyelvek II. JAVA EA+GY 1. gyakolat

Programozási alapismeretek 4.

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Java és web programozás

Programozás III KIINDULÁS. Különböző sportoló típusok vannak: futó, magasugró, focista, akik teljesítményét más-más módon határozzuk meg.

JAVA PROGRAMOZÁS 3.ELŐADÁS

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

Java V. Osztályszint. lyszintű ű tagok. Példányváltozó. Osztályváltozó. Általános Informatikai Tanszék Utolsó módosítás:

Java III. I I. Osztálydefiníció (Bevezetés)

Web-technológia PHP-vel

Objektumorientált programozás C# nyelven

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

Java III. I I. Osztálydefiníció (Bevezetés)

Java és web programozás

OOP: Java 8.Gy: Gyakorlás

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

II. labor Az alábbi osztálydiagram (2.10 ábra) alapján hozzuk létre a diagramban feltüntetett csomagokat, interfészt és osztályokat.

Bevezetés a Programozásba II 8. előadás. Polimorfizmus Giachetta Roberto

Programozási technológia

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

Generikus Típusok, Kollekciók

Mi a különbség az extends és az implements között. Mikor melyiket kell használni? Comperable-t megvalósító oasztályokban össze lehet hasonlitani

Bevezetés a Python programozási nyelvbe

Előzmények

1. Öröklés Rétegelés Nyilvános öröklés - isa reláció Korlátozó öröklődés - has-a reláció

Objektumelvű alkalmazások fejlesztése 6. gyakorlat. Öröklődés, polimorfizmus. Öröklődés Kódismétlődés objektum-orientált szerkezetben

Segédanyag: Java alkalmazások gyakorlat

Enterprise JavaBeans 1.4 platform (EJB 2.0)

Enterprise JavaBeans. Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem. Az Enterprise JavaBeans

Programozás BMEKOKAA146. Dr. Bécsi Tamás 5. előadás

Kivételkezelés, beágyazott osztályok. Nyolcadik gyakorlat

Öröklés és Polimorfizmus

Programozás. Objektum Orientált Programozás (OOP) Alapfogalmak. Fodor Attila

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Csíkszereda IRT 6. kurzus

Programozási nyelvek II.: JAVA, 11. gyakorlat

C++ programozási nyelv

Magas szintű programozási nyelvek 2 Előadás jegyzet

ELTE SAP Excellence Center Oktatóanyag 1

Programozási nyelvek Java

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error


C++ programozási nyelv

Programozás. C++ osztályok. Fodor Attila. Pannon Egyetem Műszaki Informatikai Kar Villamosmérnöki és Információs Rendszerek Tanszék

Programozás II gyakorlat. 6. Polimorfizmus

OOP. Alapelvek Elek Tibor

Programozási technológia

Pénzügyi algoritmusok

ISA szimulátor objektum-orientált modell (C++)

Java VII. Polimorfizmus a Java nyelvben

7. K: JAVA alapok Konzultáció

JUnit. JUnit használata. IDE támogatás. Parancssori használat. Teszt készítése. Teszt készítése

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

Collections. Összetett adatstruktúrák

Objektumok inicializálása

Programozási nyelvek II. JAVA EA+GY 1. gyakolat

C++ programozási nyelv Konstruktorok-destruktorok

Globális operátor overloading

Java. Perzisztencia. ANTAL Margit. Java Persistence API. Object Relational Mapping. Perzisztencia. Entity components. ANTAL Margit.

Átírás:

Objektumorientált programozás Java-ban

Objektumorientált fejlesztés Klasszikus alapszakaszok: Elemzés (analízis) specifikáció, használati esetek (use case diagramok), domain analysis Tervezés (design) osztály-, szekvencia-, kollaborációs-, és állapotdiagramok Megvalósítás (implementálás) - kód Tesztelés komponens és integrációs Karbantartás Modern fejlesztési stratégiák Modellezési nyelvek (egységesítés): 1991 James Rumbaugh OMT (Object Modelling Technique) 1991 Grady Booch Booch Method 1992 Ivar Jacobson OOSE (Object Oriented System Engineering) 1997 - Rational Software Corporation Three Amigos UML (Unified Modelling Language) RUP (Rational Unified Process) CASE (Computer Aided System Engineering) eszközök: Rational Rose, StartUML stb.

Osztályok és objektumok ADT (Abstract Data Types): adatok + az adatokkal végrehajtható műveletek Osztályok: adattípus meghatározása, melynek alapján példányokat (objektumokat) hozhatunk létre adatrejtés, öröklődés, polimorfizmus Objektum: adatok (attribútumok) + műveletek (metódusok az adatokat feldolgozó kód) Objektum állapota: az attribútumok aktuális értékei határozzák meg Objektumok beazonosítása: referenciák segítségével Kommunikáció: kliens szerver modell Kliens Szerver egy objektum (kliens) kéri egy másik objektumtól (szerver) bizonyos művelet végrehajtását. A kérés egy üzenet, gyakorlatilag a szerver objektum valamelyik nyilvános (publikus) metódusának meghívása. Ehhez a kliensnek rendelkeznie kell a szerverre mutató referenciával: public class Server { public class Client { Server s;

Objektumorientált fejlesztés public class Person { //az attributumok: public String name; public int age; //a konstruktor: public Person (String n, int a) { name = n; age = a; //a metodusok //nem adunk meg konkret implementaciot: public void talk() { public void learn() { Person +name: String +age: int +Person(n: String, a: int) +learn(): void +talk(): void p1 : Person name = Jancsi age = 18 p2 : Person name = Juliska age = 18 Példányosítás: Person p1 = new Person ( Jancsi, 18); Person p2 = new Person( Juliska, 18); Hozzáférés módosítók: private (-), public (+), protected (#), friend (package)

Osztályok közötti kapcsolatok Ismerettségi viszony Tartalmazási viszony Gyenge (aggregation) Erős (composition) Számosság szerint: Egy az egyhez (one to one) Egy a többhöz (one to many) Több a többhöz (many to many) * Car Professor Box drives communicates Gift Driver Student Student * Dog Head Town Country Capital 1..* 1 1 1 Student 10..100 1 Course Man marriage Woman 0..1 0..1

Típusmódosítók Osztályok esetében: final nem lehet belőle származtatni abstract alaposztályként alkalmazható, nem példányosítható Metódusok esetében: static osztálymetódusok, meghívásukhoz nem szükséges példányosítás, az osztály nevével hívjuk meg őket: osztalynev.metodus() (pl. Integer.toString( )). Csak statikus attribútumokkal végezhetnek műveleteket és nem hívhatnak meg nem statikus metódusokat. abstract csak abstract osztályokban deklarálhatóak, nincsenek implementálva, a származtatott osztályok kötelesek ezeket implementálni final nem újradefiniálhatóak native platformfüggő programozási nyelvben (pl. C++) vannak implementálva synchronized kritikus erőforrásokhoz való hozzáférés Attribútumok esetében: static osztály szintű változó, mindenik példány ugyanazt az értéket használja final csak egyszer történhet értékadás, konstansok deklarációjánál alkalmazhatjuk. Figyelem: egy referencia esetében a final használata nem jelenti azt, hogy a referencia által azonosított objektum állapota (attribútumainak értéke) nem változhat, csak azt, hogy a referencia nem átirányítható transient perzisztens változó, a program leállásakor az értéke megmarad volatile a változó értéke külső hatásra változhat

Öröklődés class A { A(String a) { System.out.println("Az A osztály konstruktora "+a); Person class B extends A { B(String b) { super(b); System.out.println("A B osztály konstruktora "+b); +name: String +age: int +talk(): void +learn(): void public class Example { public static void main(string[] args) { B b = new B("Hi"); Student +year: int +learn(): void Professor +department: String +talk(): void Az A osztály konstruktora Hi A B osztály konstruktora Hi

Öröklődés metódusok túlterhelése (method overloading): az osztályon belül több metódus azonos névvel - a paraméterlista és esetenként a visszafordított típus különbözik. Statikus kötés a metódus címe már a kompilálási fázisban ismert. metódusok újradefiniálása (method overriding): a származtatott osztályok újradefiniálják az alaposztály metódusait. Dinamikus kötés. Java-ban nem megengedett a többszörös öröklés (gyémántöröklés problémájának kiküszöbölése) A B C D Alaposztály paraméteres konstruktorának meghívása, a származtatott osztály konstruktorának elején: super( ) A this és super referenciák this: az aktuális példányra hivatkozik super: az alaposztályra hivatkozik

Polimorfizmus Polimorfizmus (többalakúság): egy B típusú objektum egy adott helyzetben A típusúként jelenik meg, és A típusú objektumként használjuk. Természetesen ez csak akkor lehetséges, ha a két osztály (A és B) között származtatási viszony áll fent. Mivel a származtatott osztály örökli az alaposztály tulajdonságait, használható minden olyan helyzetben, ahol az ős használható. Az angol terminológiában ezt a helyzetet a B is A kifejezés érzékelteti (amennyiben B az A leszármazottja). Vigyázat: a kijelentés fordítottja már nem igaz. Egy egyszerű példa: a négyszög (A) osztályból származtatjuk a négyzet (B) osztályt. A négyzetről elmondható, hogy négyszög, de természetesen nem minden négyszög négyzet. A származtatott osztály az őshöz képest új tulajdonságokkal is rendelkezhet, így előállhatnak olyan helyzetek, amikor az ős nem helyettesítheti utódját. Egy négyzet (B) objektumot, viszont bármilyen helyzetben kezelhetünk négyszögként, így semmi akadálya, hogy egy négyszög típusú referencia egy négyzet objektumra mutasson.

Polimorfizmus egy referencia esetében beszélhetünk statikus és dinamikus típusról, vagy kötésről. A statikus típus az, amely a deklarációban szerepel, a dinamikus típus pedig a referencia által aktuálisan beazonosított objektum típusa. mi történik akkor, ha egy A típusúként deklarált referencia adott pillanatban egy B típusú objektumra mutat, és segítségével meghívunk egy metódust, melyet a B osztály újradefiniált? A metódusnak melyik változata fog érvényesülni? Természetesen, ha újradefiniáltuk a metódust, valószínűleg azt szeretnénk, hogy az új, a konkrét típusnak megfelelő implementáció érvényesüljön. De ez nem minden nyelvben történik automatikusan így. Pl.: C++ virtuális tagfüggvények A Java nyelvben a metódusok újradefiniálásának esetében mindig az objektum konkrét típusának megfelelő implementáció érvényesül (dinamikus kötés). Azt is mondhatnánk, hogy a Java-ban minden tagfüggvény virtuális.

Absztrakt osztályok Származtatás és polimorfizmus egy rendszeren belül létrehozható közös alap különböző, de azonos alaptulajdonságokkal is rendelkező objektumok részére. Ez lehetővé teszi, hogy azokban az esetekben, amikor csak a közös tulajdonságok relevánsak, azonos módon hivatkozzunk ezekre az objektumokra. Ezt egyszerűen megtehetjük akkor, ha az osztályok rendelkeznek egy közös őssel. Előállhatnak olyan esetek, amikor az ősosztálynak nem lehetnek példányai, vagy a rendszer szempontjából értelmetlen lenne a példányosítás. Példa: mértani alakzatokat megjelenítő felület. Az alakzatok rendelkeznek közös tulajdonságokkal (pozíció, szín, stb.), de nem lenne értelme, hogy egy általános alakzat objektumot hozzunk létre. A közös tulajdonságok nem lennének elegendőek a megjelenítéshez. Mégis hasznos lenne, ha a különböző alakzatoknak megfelelő osztályok rendelkeznénk egy közös őssel, hogy bizonyos esetekben egységesen hivatkozhassunk rájuk. Absztrakt metódusok és osztályok: Java-ban abstract kulcsszóval jelöljük az absztrakt metódusokat, és nem adunk meg konkrét implementációt. Ha egy osztálynak van egy absztrakt metódusa, absztrakt osztályról van szó, és ezt a fejlécben jeleznünk kell. Az absztrakt metódusokat általában a származtatott osztályok implementálják. Ha ezt mégsem teszik, akkor az illető származtatott osztályt is absztraktnak kell deklarálni. Közös felület/viselkedési mód meghatározása

Interfészek Interfész általánosan: rendszerek közötti kommunikációnál egy adott rendszer interfésze írja le, hogy kívülről hogyan lehet hozzáférni a rendszerhez Osztályoknál: tulajdonképpen az osztály interfészét a publikus adattagok és metódusok alkotják Java-ban további jelentés: Interfész típus deklaráció, mely egy bizonyos viselkedési módot határoz meg. Konstansokból és nem implementált metódusokból (metódus prototípusokból) áll. Azok az osztályok, amelyek megvalósítják (implementálják) az illető interfészt, kötelező módon implementálják az abban deklarált metódusokat (minden metódust) Úgy is tekinthetünk az interfészekre, mint szerződésekre, amelyeket az implementáló osztályoknak be kell tartaniuk. Ha egy osztály megvalósít egy adott interfészt, vállalja azt, hogy az interfésznek megfelelően fog viselkedni. Alkalmazás: hasonlóságokkal bíró osztályok részére egy közös alap létrehozása, függőségek feloldása Egy osztály több interfészt is megvalósíthat (különbség az absztrakt osztályokhoz viszonyítva)

Interfészek Interfész public interface Resizable { public void resize(dimension d); Megvalósító osztály public class Circle implements Resizable { public void resize(dimension d) { //a kör újraméretezését megvalósító kód Main: public static void main(string[] args) { Circle c = new Circle(); c.resize(new Dimension(100,100)); Resizable s = new Circle(); s.resize(new Dimension(100,100)); Más példa: gyűjtemények Pl. List interface

Interfészek az interfészek metódusai alapértelmezetten nyilvánosak (a public kulcsszó használata opcionális) Az interfészek esetében is beszélhetünk öröklődésről, egyik interfész lehet egy másik interfész leszármazottja Alkalmazás példa: egy interfésznek már léteznek megvalósításai és ki szeretnénk egészíteni további metódusokkal. Az összes megvalósító osztályt módosítanunk kellene. Jobb megoldás lehet a származtatás (a származtatott interfészben kapnak helyet az új metódusok). Észrevétel: az interfészek megvalósításánál a szerződés betartása, csak azt jelenti, hogy az interfész metódusait a megvalósító osztály implementálja, tehát egy az osztály példányára mutató referencia segítségével ezek a metódusok meghívhatóak. Ez a vállalás az implementációs részletekkel, a megvalósítás hogyanjával kapcsolatban semmiféle garanciát nem jelent. Például, az is lehetséges, hogy egy adott interfészt megvalósító osztály valamelyik metódust olyan módon implementálja, hogy kivételt dob a metóduson belül, vagy egyszerűen üresen hagyja a metódus törzsét.

Interfészek Függőségek feloldása, példa: egy metódus egy karakterláncokból álló listát vár, hogy az elemeit kiírja a konzolra. A lista többféleképpen megvalósítható. Például, az elemeket tárolhatjuk tömbben, vagy láncolt listát alkalmazhatunk. A feladat szempontjából ezek az implementációs részletek nem relevánsak. Csak az fontos, hogy a paraméterként kapott objektum rendelkezzen a listák alapvető tulajdonságaival, például lehessen egy iterátor segítségével bejárni, hogy kiírhassuk az elemeit. Fölösleges lenne megkötnünk a metódusunkat használó programozó kezét azzal, hogy rákötelezzük egy adott implementáció alkalmazására. A megoldás: a paraméter típusát interfész segítségével határozzuk meg. Más példa: alkalmazás-programozási felületek (API Application Programming Interface): egy cég komplex műveleteket megvalósító osztályokat tartalmazó szoftvercsomagot készít. A csomagot egy másik cég fogja felhasználni saját alkalmazásának fejlesztésekor. A tipikus eljárás, hogy az osztályok publikus interfészeknek lesznek a megvalósításai. A publikus interfészek segítségével lehet majd meghívni az osztályokon belül implementált metódusokat az implementációs részletek ismerete nélkül. Komponens alapú programozás, szolgáltatásorientált architektúrák Összefoglaló megjegyzés: érdemes "interfészekben gondolkodni"!

Beágyazott osztályok Belső osztály (inner class): class A { A(){ class B { B() { public void doit() { System.out.println("Hello"); ; public class Example { public static void main(string[] args) { A a = new A(); A.B b = a. new B(); b.doit(); Név nélküli belső osztály:... addwindowlistener(new WindowAdapter() { public void windowclosing(windowevent e) { System.exit(0); );... Statikus beágyazott osztály (static nested class): class A { A() { static class B { B() { public static void doit() { System.out.println("Hello"); ; public class Example{ public static void main(string[] args) { A.B.doIt(); osztályok deklarálása más osztályok belsejében nem tartalmazhatnak statikus metódusokat, kivéve a statikus belső osztályokat a nem statikus belső osztályok példányosítását minden esetben a külső osztály példányosítása előzi meg

Object ősosztály getclass(): az objektum típusának futási időben történő meghatározása. Egy Class típusú objektumot térít vissza, amelynek segítségével az osztályról kérhetünk különböző információkat. equals(): az objektumok egyenlőségét vizsgálja. Általában a metódust a tartalom, az állapot összehasonlítására szokás használni. Bár az Object osztály alapértelmezett implementációja csak a referenciák azonosságát vizsgálja, a származtatott osztályokban ez a metódus általában olyan módon van újradefiniálva, hogy mélyebb, tartalmi összehasonlításra adjon lehetőséget. Például String objektumok esetében akkor fog igaz eredményt (true értéket) adni, ha a karakterláncok azonos karakterekből állnak. hashcode(): egy egész értéket, az objektum hash kódját téríti vissza, amely gyakran szükséges, amikor az objektumokat hasító táblákban tároljuk. A metódus a kódot a példány aktuális állapotának függvényében képezi. Ha két objektum állapota azonos (tartalma megegyezik), hash kódjuk is megegyezik. Következményként, ha újradefiniáljuk az equals metódust, akkor általában a hashcode metódust is újra kell definiálnunk. Az Object osztály alapértelmezett metódusa a memóriacím alapján képezi a kódot. A metódus újradefiniálásánál fontos, hogy minden olyan adattagot felhasználjunk a kód generálásához, amelyet az equals metóduson belül felhasználtunk az összehasonlításhoz.

Object ősosztály tostring(): az objektum egy szöveges reprezentációját téríti vissza. Az Object osztály implementációja az osztály nevét és a hash kódot fűzi egybe, de természetesen ez a metódus is újradefiniálható. finalize(): az objektum által foglalt memóriaterület felszabadítása előtt hívja meg a szemétgyűjtő. Az Object osztály nem ad implementációt erre a metódusra. A származtatott osztályokban tipikusan az objektum által foglalt erőforrások felszabadítására alkalmazzák. clone(): másolat készítése az osztály egy már létező példányáról. A metódus fejléce: protected Object clone() throws CloneNotSupportedException A másolat készítése csak akkor valósítható meg, ha az osztály implementálja a Cloneable interfészt. Az Object ősosztály ezt nem teszi meg. Ha egy az interfészt nem implementáló osztály példányáról szeretnénk a clone metódushívás segítségével másolatot készíteni, a CloneNotSupportedException típusú kivételt kapjuk futási időben. Ha a másolat elkészíthető, akkor egy az eredeti objektummal megegyező állapotú új objektumot kapunk eredményül. Megjegyzendő, hogy az adattagokról nem készül másolat (ezek nem lesznek klónozva ), így alapértelmezetten a metódushívás egy sekély másolást (shallow copy) eredményez, nem készül mély másolat (deep copy). Természetesen a clone metódus újradefiniálható, és így mély másolat is készíthető. wait(), notify(), notifyall() később tárgyaljuk (végrehajtási szálak, szinkronizálás)

Csomagok Osztályok és interfészek csoportja jar tömörítő Létrehozás: package MyPackage; public class MyBaseClass {.. package MyPackage; public class MyDerivedClass extends MyBaseClass {.. Használat: java.awt.button b; MyPackage.MyBaseClass ob; MyPackage.MyDerivedClass od; vagy: import java.awt.button; import MyPackage.MyBaseClass; import MyPackage.MyDerivedClass vagy: import java.awt.*; import MyPackage.*;

Példa core Person #name: String #age: int +Person(String, int) +getname(): String +setname(string): void +getage(): int +setage(int): void collection <<inner class>> StudentIteratorImpl -index: int StudentIterator +hasmoreelements(): boolean +nextelement(): Student Student -faculty: String +Student(String, int, String) +getfaculty(): String +setfaculty(string): void +tostring(): String TestStudentList * +StudentIteratorImpl() +hasmoreelements(): boolean +nextelement(): Student StudentList -current: int -students: array of Student +StudentList(int size) +addstudent(student): void +getiterator(): StudentIterator +main(string[] args): static void