[[oktatas:programozás|< Programozás]] ====== Objektum Orientált Programozás ====== * **Szerző:** Sallai András * Copyright (c) 2011, Sallai András * Szerkesztve: 2011, 2014, 2015 * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]] * Web: https://szit.hu ===== Bevezetés ===== Itt csak egy rövid összefoglalót találunk az objektum orientált programozásról. A objektum orientált programok konkrét megvalósítását lásd az adott programozási nyelvnél. Az angol **Object-Oriented Programming** szavakból alkotott betűszó, röviden **OOP**. A valós világot úgy próbálja meg modellezni, hogy az sokkal közelebb álljon a valósághoz. A műveletek megalkotása helyett objektum hierarchiákat hozunk létre. A valós világból a számítógépen olyan olyan objektumokat hozunk létre, aminek tulajdonságai és viselkedéseik vannak. Az egyes nyelvekhez tartozó Objektum Orientált megvalósításokat lásd a konkrét nyelveknél, itt csak rövid áttekintést találunk. ===== Osztály ===== Az osztály, angolul class. Egy egyed leírása, amiről információkat tárolunk. Ez az információ a programozási nyelvben változókat, és a változókon elvégzett műveletekből (eljárás, metódus) áll. Felépíthetjük például a Dolgozók osztályát. A dolgozónak tárolhatjuk tulajdonságait. A tulajdonságok az osztály egy-egy változójában kapnak helyet. Például a dolgozó neve, kora, születésének ideje, fizetése, stb. A metódusok, beállíthatják, lekérdezhetik a tulajdonságokat. Például a nevet, a születést, vagy meghatározhatják az osztály egyéb viselkedését. Az osztályra úgy szokás tekinteni, mint az **objektum terve**. Még nem egy konkrét valamit ír le, csak egy terv. ===== Mező ===== A osztályok és objektumok tulajdonságait néha mező néven említjük. Ezek az osztály változói. A mezők, a tulajdonságok, az attribútumok így ugyanazt jelölik. A C# nyelv tartalmaz úgynevezett tulajdonság létrehozási lehetőséget, így ott a "tulajdonság" szónak más jelentése is van. ===== Metódus ===== A mezőkön végrehajtható eljárások és függvények összefoglaló neve. A osztály viselkedésének is mondjuk. ===== Osztály létrehozása ===== Osztályt általában a class kulcsszóval vezetjük be, utána pedig a nevét adjuk meg. class Szemely { String nev; int kor; } {{:oktatas:programozas:class_pelda.png?400|}} A mezők és a metódusok alkotják az osztály tagjait. {{:oktatas:programozas:metodus_pelda.png?400|}} {{:oktatas:programozas:mezok_pelda.png?400|}} ==== Python megközelítésben ==== {{:oktatas:programozas:osztaly_letrehozasa_3.png|}} ===== Konstruktor ===== A konstruktor egy speciális metódus. Speciális mivel lefut egy objektum létrehozása során. Néhány nyelven a konstruktor neve megegyezik az osztály nevével. Ilyen a Java, C#. De a Python nyelvben a konstruktor neve __init__() A konstruktornak nem jelölhetünk meg visszatérési értéket, mivel alapértelmezett feladat hogy visszaadja az osztály egy példányát. Konstruktor Java és C# nyelven: class Szemely { public String nev; public int kor; public Szemely() { this.nev = "névtelen"; this.kor = -1; } } {{:oktatas:programozas:konstruktor_pelda.png?400|}} A konstruktor mindig akkor fut le, amikor egy objektumot létrehozunk. ==== Konstruktor Python módra ==== {{:oktatas:programozas:osztaly_letrehozasa_konstruktor.png|}} ===== Destruktor ===== Némely nyelvben van destruktor is. A destruktor akkor hajtódik végre, ha valamilyen objektumot megszüntetünk. A Java nyelvben nem használunk destruktort. A programozási nyelvekben általában a destruktor neve is megegyezik az osztály nevével, de egy ~ karaktert szokás elé tenni. ===== Objektum ===== Az osztály egy példányosított változata. A fenti Dolgozó osztályból ha egy példányt hozunk létre, az már egy konkrét dolgozó lesz. Lehet például egy "Nagy József" nevű dolgozó, aki 28 éves, 480000 - Ft a fizetése. Az objektumnak is adnunk kell egy nevet. Például Joska. Példa Java és C# nyelven: Dolgozo janos = new Dolgozo(); {{:oktatas:programozas:peldanyositas.png?400|}} Az objektumot az osztályból hozzuk létre. Olyan ez mint egy változó létrehozása. Az egyenlőség jel jobboldalán a new kulcsszó való az objektum példány létrehozására. A new után mindig a konstruktort hívjuk. ===== Elérés ===== Az osztály egyes tagjai (változók és metódusok) elérése változtatható. * A **public** elérés, azt jelenti, hogy az adott tag más osztályokból is elérhető. * A **private** elérés, azt jelenti, hogy más osztályokból nem érhető el a tag, még az örökölés lévén létrejött osztályokban sem. * A **protected** elérés, az jelenti, hogy csak az örökölés során létrehozott osztályokban érhető el. ===== Öröklés ===== Egy osztályból újabb osztályt hozhatunk létre, ennek folyamatát nevezzük öröklésnek. Az öröklés során az új osztály örökli az előző minden tagját, beleértve a mezőket és a metódusokat. Öröklés Java nyelven: class Szemely { String nev; int kor; } class Dolgozo extends Szemely { String munkakor; } Öröklés C# nyelven: class Szemely { public String nev; public int kor; } class Dolgozo : Szemely { String munkakor; } ===== Többalakúság ===== A metódusok és a konstruktorok több alakban is meghívhatók. Az osztályok öröklés révén több formában is példányosíthatók. Ezeket a lehetőségeket nevezzük többalakúságnak. ==== Többalakúság örökléssel ==== class Allat { public void eszik() { System.out.println("evés..."); } } class Macska extends Allat { public void nyavog() { System.out.println("miau"); } } public class Tobbalakusag_01 { public static void main(String[] args) { Macska macska = new Macska(); Allat allat; allat = macska; macska.eszik(); macska.nyavog(); allat.eszik(); /* Az allat objektum a macska objektumra mutat, mégsem lehet futtatni az allat objektumon a nyavog() metódust. Mintha több alakja lenne. */ } } ==== Többalakúság interfésszel ==== interface Allat { public void beszel(); } class Macska implements Allat { public void beszel() { System.out.println("miau"); } } class Kutya implements Allat { public void beszel() { System.out.println("vau"); } } public class Program01 { public static void main(String[] args) { Allat a = new Macska(); Allat b = new Kutya(); a.beszel(); b.beszel(); } } ==== Függvény paraméter és öröklés ==== public class Program01 { public static void main(String[] args) { Macska macska = new Macska(); Kutya kutya = new Kutya(); Allat allat = new Allat(); beszeltet(allat); beszeltet(macska); beszeltet(kutya); } public static void beszeltet(Allat allat) { allat.beszel(); /* Az allat objektum másként viselkedik ha macska objektumot kap, és másként ha kutya objektumot kap */ } } class Allat { public void beszel() { System.out.println("aaaaa"); } } class Macska extends Allat { public void beszel() { System.out.println("miau"); } } class Kutya extends Allat { public void beszel() { System.out.println("vau"); } } ==== Függvény paramétere és interfész ==== public class Program01 { public static void main(String[] args) { Macska macska = new Macska(); Kutya kutya = new Kutya(); beszeltet(macska); beszeltet(kutya); } public static void beszeltet(Allat allat) { allat.beszel(); /* Az allat objektum másként viselkedik ha macska objektumot kap, és másként ha kutya objektumot kap */ } } interface Allat { public void beszel(); } class Macska implements Allat { public void beszel() { System.out.println("miau"); } } class Kutya implements Allat { public void beszel() { System.out.println("vau"); } } ===== Virtuális metódus ===== Egy metódus akkor virtuális, ha az örökölt osztályokban felülírható. A programozási nyelvekben ezt az ősosztályban kell beállítani, általában a virtual kulcsszóval. A Java nyelvben nem szükséges ezt megtenni, mivel minden metódus alapértelmezettként felülírható, vagyis virtuális. De pascal nyelven például: point = Object(location) visible: boolean; Constructor Init(InitX, InitY: integer); Procedure Show; Virtual; Procedure Hide; Virtual; Function IsVisible: boolean; Procedure MoveTo(NextX, NextY: integer); End; Vegyük észre a Virtual kulcsszót a Show és a Hide eljárásnál. ===== Kérdések ===== - Mivel dolgozunk objektum orientált programozásban? - Mik az osztályok? - Egy objektumorientált programozási nyelvben a viselkedés hogyan van leképezve? - Mi a különbség az osztály és az objektum között? - Mi a mező? - Mi a metódus? - Mi a konstruktor? - Mi a destruktor? - Mi az elérés? Milyen elérési szinteket ismer? - Mondjon példát, az egyes programozási nyelvekben hogyan valósítják meg az öröklést? - Mi a többalakúság? - Mi a virtuális metódus? - Hogyan teszünk Java nyelvben egy metódust virtuálissá? - Milyen metódust hívunk meg példányosításnál? - Milyen kulcsszót használunk példányosításnál? - A példányosított objektum rendelkezik az osztályok valamelyik tulajdonságával? ===== Feladatok Java megoldásokkal ===== ==== Feladat 001 ==== Készítsen egy osztályt, amely járművek rendszámát és kivitelét tárolja. A járművek a következő kivitelűek lehetnek: buggi, cabrio, coupe, egyteru, ferdehatu, hot rod, kisbusz, kombi, lépcsős hátú, moped, pickup, sedan, sport, terepjáró. Írja meg azokat a metódusokat, amelyek lekérdezik, illetve beállítják a két mező értékét. A programban vegyen fel egy példajárművet, majd határozza meg a rendszámát, és a kivitelét, majd írassa a képernyőre a kivitelt. class Jarmu { //Mezők private String rendszam; private JarmuKivitel kivitel; //Metódusok public String lekerRendszam() { return this.rendszam; } public void beallitRendszam(String atvettRendszam) { this.rendszam = atvettRendszam; } public JarmuKivitel lekerKivitel() { return this.kivitel; } public void beallitKivitel(JarmuKivitel atvettKivitel) { this.kivitel = atvettKivitel; } } enum JarmuKivitel { BUGGI, CABRIO, COUPE, EGYTERU, FERDEHATU, HOT_ROD, KISBUSZ, KOMBI, LEPCSOSHATU, MOPED, PICKUP, SEDAN, SPORT, TEREPJARO } public class Program01 { public static void main (String[] args) { Jarmu jarmu = new Jarmu(); jarmu.beallitRendszam("ABC-123"); jarmu.beallitKivitel(JarmuKivitel.MOPED); System.out.println("Példa jarmu: " + jarmu.lekerKivitel() ); } } ==== Feladat 002 ==== Ingatlanok adatait szeretnénk nyilvántartani. Ehhez kell egy osztályt elkészítenie. Mit kell tárolni? Eladó vagy kiadó az ingatlan? Ár, alapterület, szobák száma, típus: tégla, panel, csúsztatott zsalus. Emeletek: mi felett? Szuterén, földszint, félemelet, 1,2 ..10, 10 felett Lift: van vagy nincs. Erkély: van vagy nincs. Állapot: beköltözhető, építés alatt, új építésű, újszerű, felújított, közepes állapotú, felújítandó, jó állapotú Fűtés: gáz (cirko), gáz (konvektor), gáz (héra), távfűtés, távfűtés egyedi méréssel, elektromos, házközponti, házközponti egyedi méréssel, fan-coil, geotermikus, cserépkályha, egyéb. Komfort: luxos, duplakomfortos, összkomfortos, komfortos, félkomfortos, komfort nélküli. Lehetséges Java megoldás: enum Status { ELADO, KIADO } enum Tipus { TEGLA, PANEL, ZSALUS} enum EmeletFelett { SZUTEREN, FOLDSZINT, FELEMELET, EGY, KETTO, HAROM, NEGY, OT, HAT, HET, NYOLC, KILENC, TIZ, TIZ_FELETT } enum Allapot { BEKOLTOZHETO, EPITES_ALATT, UJ_EPITESU, UJSZERU, FELUJITOTT, KOZEPES, FELUJITANDO, JO } enum Futes { GAZ_CIRKO, GAZ_KONVEKTOR, GAZ_HERA, TAVFUTES, TAVFUTES_EGYEDI, HAZKOZPONTI, HAZKOZPONTI_EGYEDI, FAN-COIL, GEOTERMIKUS, CSEREPKALYHA, EGYEB } enum Komfort { LUXUS, DUPLA, OSSZ, NORMAL, FEL, NINCS } class Ingatlan { Status status; double ar; int alapterulet; int szobakSzama; Tipus tipus; EmeletFelett emeletFelett; Allapot allapot; Futes futes; Komfort komfort; } public class Program01 { public static void main (String[] args) { System.out.println("Hi"); } } ===== Függelék ===== ==== Hasonlat ==== | Nagy József | egy objektum | | József születési adat | tulajdonság | | Jóska ehet, ihat, alhat, beszélhet stb. | metódus | | Jóska a **programozók** egy példánya | osztály | | Jóska egy másik objektumon alapszik, \\ amit programozóknak hívnak | prototípus | | Jóska megtartja magának a jogot, hogy \\ kiszámítsa életkorát a születési adatok alapján. | egységbezárás | | Nem szükséges ismerni, hogy számítjuk \\ ki Jóska életkorát. | információs rejtés | | Jóska a fejlesztői csapat része, amelybe \\ beletartozik Mari grafikus és Kati nyelvész | Absztrakció | | Jóska, Mari és Kati a személy objektumon \\ alapszik. | Öröklés | | Mindenki beszél, de mindenki mást mond: \\ Jóska:beszél, Mari:beszél, Kati:beszél | többalakúság | ===== Irodalom ===== ==== Könyvek ==== * Bert Bates, Kathy Sierra: Agyhullám: Java * Angster Erzsébet: Az objektumorientált tervezés és programozás alapjai * Angster Erzsébet: Objektumorientált Tervezés és Programozás - JAVA I. kötet * Angster Erzsébet: Objektumorientált Tervezés és Programozás JAVA II. Kötet ==== Linkek ==== * http://spillerlaszlo.wordpress.com/programozasi-tesztek/oop/ * http://wiki.prog.hu/wiki/Objektumorient%C3%A1lt_programoz%C3%A1s * http://hu.wikipedia.org/wiki/Objektumorient%C3%A1lt_programoz%C3%A1s