1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 5. gyakorlat
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor2Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Objektumorientáltság Egységbezárás és információ elrejtése (absztrakt adattípus) –Adatok és rajtuk végzett műveletek egységbezárása (osztályok írása, múlt hét) Öröklődés Polimorfizmus (többalakúság)
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor3Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Öröklődés Lényege: hasonló osztályokat ne kelljen újra létrehozni, hanem a már meglévő osztályt módosítani Specializálás és általánosítás –specializálás: őstől a gyerek felé (egyre speciálisabb osztályokat látunk) –általánosítás: a gyerektől az ős felé (egyre általánosabb osztályokat láthatunk)
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor4Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Öröklődés Adattagok: –újakat hozhatunk létre (az örököltek is megmaradnak) Metódusok: –újakat hozhatunk létre –már meglévőket írhatunk felül (overriding) Java-ban csak egyszeres öröklődés van (azaz egy gyerekosztály csak egy ősből származik)
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor5Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Overriding vs overloading Overriding: –Már meglévő metódus felülírása egy gyerekosztályban –Azonos név és paraméterlista Overloading: –Egy osztályon belüli metódusok –Egy metódusnév, de különböző paraméterlista
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor6Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Öröklődés Java-ban az extends kulcsszóval –class GyerekOsztály extends ŐsOsztály { //... } Az ősosztálytól örökölt privát adattagok részei lesznek a származtatott osztálynak –de csak a publikus getter/setter metódusokkal tudjuk őket elérni –konstruktorból az ősosztály konstruktorának hívásával, a super kulcsszóval
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor7Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor This/super this: hivatkozás az aktuális objektumra –hivatkozás az aktuális objektum egy másik konstruktorára egy adattagjára kiíratáskor super: hivatkozás az ősre –hivatkozás az ősosztály egy konstruktorára egy metódusára
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor8Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Példa: Ősosztály public class Allat{ private String fajnev; private int varhatoElettartam; public Allat(String fajnev, int vElettartam){ this.fajnev = fajnev; this.varhatoElettartam = vElettartam; }
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor9Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Példa: Gyerekosztály public class Hal extends Allat{ private int uszonyhossz; public Hal(String f, int v, int u){ super(f, v); //Ős konstruktorának hívása uszonyhossz = u; } A Hal rendelkezik az Állat összes adattagjával, valamint egy sajáttal (uszonyhossz)
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor10Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Polimorfizmus (Többalakúság) Objektumok felcserélhetőségét biztosítja Fordításkor még nem tudjuk, hogy melyik konkrét operáció fog meghívódni (örökölt vagy felüldefiniált) –Futás közben derül ki a konkrét típus alapján –kései kötés: Java-ban minden metódushívás ilyen Objektumot az őstípusa alapján kezeljük –Minden gyerektípus egyben őstípusú is –Fordítva nem igaz! –Őst váró metódus kaphat gyerek típust is
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor11Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Polimorfizmus Előnyei: –A kód nem függ a specifikus típusoktól –Utólag is lehet definiálni származtatottakat Példakód: Test.java
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor12Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Object (implicit öröklés) Java-ban minden osztály (a beépítettek és az általunk írtak is) implicit módon az Object nevű ősosztályból származik (közvetve vagy közvetlen) –tehát az osztályhierarchia tetején mindig az Object áll –az Object típusú változó bármilyen objektumra hivatkozhat –ha egy metódus Object típusú paramétert vár, akkor annak bármilyen típusú objektumot átadhathatunk
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor13Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor A toString() metódus Az Object osztály biztosít számunkra néhány hasznos metódust, melyet a származtatott osztályok felüldefiniálhatnak (de nem kötelező) –pl.: clone(), equals(), hashCode(), finalize(), toString, getClass(), notify(), notifyAll(), wait() Egyik fontos ilyen metódus a toString() A toString() az objektumot Stringként reprezentálja Teszteléskor hasznos lehet
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor14Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor A toString() használata Létrehozunk egy objektumot, majd ha kiíratjuk azt: –Jarmu j = new Jarmu(); –System.out.println(j); Ilyen esetben valójában a toString() metódus hívódik meg (automatikusan), amelyet ha nem definiálunk felül, akkor az Object-től örökölt toString() kerül meghívásra Példakód: Superman.java, SMMain.java
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor15Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Csomagok (packages) Az összetartozó (valamilyen szempont alapján) osztályokat csomagokba szokás szervezni A forráskódban azt, hogy egy adott osztály melyik csomagba tartozik az alábbi módon jelöljük: –package csomagnév; A kódban az első nem komment sornak kell lennie! Egy osztálynak a teljes neve: –packagenév.osztálynév (pl.: String java.lang.String)
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor16Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Csomagok (packages) Csomag elnevezése: megállapodás által fordított domain elnevezés: –pl.: hu.u_szeged.inf inf.u-szeged.hu –Az ennek megfelelő mappaszerkezetről gondoskodni kell (hu/u_szeged/inf) Eclipse létrehozza, különben kézzel kell! Ha egy osztály nincs egyetlen csomagba sem, akkor alapértelmezetten egy default csomagba kerül
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor17Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Csomagok (packages) Egy adott csomagban lévő osztály importálása: –import csomagnév.OsztályNév; Egy adott csomagban lévő összes osztály importálása: –import csomagnév.*; Példa: –import java.util.ArrayList; –import java.util.*;
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor18Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Csomagok (packages) Egyes csomagok osztályai automatikusan importálódnak a programunkba, anélkül hogy ezt kérnénk Ilyen a java.lang összes osztálya, mint pl.: –Wrapper osztályok –Kivételek –Math osztály, String, stb..
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor19Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Statikus import import static OsztályNév; Ezek után az osztály összes statikus adattagját elérhetjük, az osztálynév nélkül is: –Pl.: a Math.PI helyett használhatjuk PI-t
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor20Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Névütközések ha két csomagunk is van ugyanolyan nevű osztállyal, névütközés lehet ha mindkettőt használni szeretnénk (amíg nem használunk ilyet, addig nincs baj) explicite ki kell írni a csomag nevét az osztály elé, amikor használjuk: myPackage.Ember e1 = new myPackage.Ember(); myNewPackage.Ember e2 = new myNewPackage.Ember();
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor21Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Absztrakt osztály Nem példányosítható (Ha megpróbáljuk, akkor fordítási hibát kapunk) Általánosítás: közös interfészt biztosít a leszármazottaknak abstract class Hangszer {... }
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor22Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Absztrakt metódus Csak a deklarációja van, definíciója nincs (nincs függvénytörzs) leszármazott osztályokban kell megvalósítani pl.: abstract public void szolj(Hang h); Ha van benne absztrakt metódus, akkor maga az osztály is absztraknak kell, hogy legyen absztrakt metódus nem lehet private és final, hiszen úgy nem lenne értelme (nem lehetne megvalósítani/felüldefiniálni)
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor23Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Interfész Olyan osztály, amiben csak absztrakt metódus van Csak egy formát ad, implementáció nélkül Nincs benne az osztályhierarchiában interface Hangszer{... }
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor24Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Interfész Metódusai: –impliciten public és abstract –nem lehet private és final implements kulcsszóval lehet interfészt implementálni több interfészt is implementálhatunk egyszerre
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor25Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Interface vs. abstract class Interface: –egyetlen metódust sem implementálhat –implementáljuk –több interface-t is implementálhatunk Abstract class: –implementálhat metódusokat –örököltetjük –csak egyszeresen örököltethetünk
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor26Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Interfész public class Zongora implements Hangszer{... } public abstract class AlkoholosItal extends Ital implements Alkoholos{... }
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor27Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Instance of Ezzel vizsgálhatjuk meg az objektum típusát public void kutyaE(Object o){ if(o instanceof Kutya){ System.out.println("Ez egy kutya."); } else { System.out.println("Ez nem egy kutya."); }
Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor28Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Feladatok Feladat (A megoldáshoz használjuk fel a PrivatEmber, Superman és SMMain osztályokat) –Készíts egy abstract Ember osztályt. –Vidd át a toString metódust az Ember osztályba, majd módosítsd úgy a programot, hogy abstract legyen a toString metódus. –A PrivateEmber osztály öröklődjön az Ember osztályból. –Probáld ki mit csinál az SMMain program, ha a toString metódust kikommentezed! –Definiálj egy Szuperkepessegek interfészt, amelynek van egy void kriptonittalSugároz() függvény osztályban, –Implementáld ezt az interfészt a PrivatEmber osztályban, ahol nem csinál semmit (esetleg kiír valamit a konzolra), de definiáld felül a Superman osztályban úgy, hogy az csökkentse a szupererőt. (Az SMMain futtatóosztály is érdemes módosítani, hogy hívja ezt a függvényt valamilyen módon.) –Helyezd csomagba a privatEmber és a Superman osztályokat. Az SMMain maradjon csomagon kívül.)