Szoftvertechnológia 4. előadás. Objektumorientált tervezés: általánosítás. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Hasonló dokumentumok
Informatikai Kar. 4. fejezet. Giachetta Roberto

Alkalmazott modul: Programozás 11. előadás. Objektumorientált programozás: öröklődés

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

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

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

Alkalmazott modul: Programozás 10. előadás. Objektumorientált programozás: tervezés és megvalósítás

Objektumorientált programozás C# nyelven

Programozási technológia

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

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

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

Bevezetés a Programozásba II 5. előadás. Objektumorientált programozás és tervezés

Programozás módszertan p.1/46

C++ programozási nyelv

Bevezetés a programozásba előadás: Öröklődés

Objektumorientált programozás C# nyelven

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

Programozási nyelvek Java

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

Interfészek. PPT 2007/2008 tavasz.

Öröklés és Polimorfizmus

Programozási nyelvek Java

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

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

Programozási alapismeretek 4.

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

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.

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

JAVA PROGRAMOZÁS 2.ELŐADÁS

Már megismert fogalmak áttekintése

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

Java VII. Polimorfizmus a Java nyelvben

és az instanceof operátor

Java VII. Polimorfizmus a Java nyelvben

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

Elemi Alkalmazások Fejlesztése II.

Objektumelvű programozás

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

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása

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

Osztályok. 4. gyakorlat

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása. Biztonságos adattípusok megvalósítása

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

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

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

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

Virtuális függvények (late binding)

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

Szoftvertechnológia 3. előadás. Objektumorientált tervezés: alapismeretek. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Osztály öröklődés. Öröklődés és polimorfizmus. Programozás II. előadás. Szénási Sándor.

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

Bevezetés a Python programozási nyelvbe

OOP. Alapelvek Elek Tibor

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

Bevezetés a programozásba Előadás: A const

OOP #14 (referencia-elv)

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Szoftverek tesztelése

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

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 PROGRAMOZÁS 3.ELŐADÁS

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

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?

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

Számítógép és programozás 2

BME MOGI Gépészeti informatika 8.

Objektum orientált programozás Bevezetés

Osztály és objektum fogalma

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

C++ programozási nyelv

Absztrakció. Objektum orientált programozás Bevezetés. Általános Informatikai Tanszék Utolsó módosítás:

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

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

Programozás II gyakorlat. 6. Polimorfizmus

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

OOP alapok Egy OOP nyelvet három fontos dolog jellemez. egységbezárás ( encapsulation objektumoknak öröklés ( inheritance

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

Web-technológia PHP-vel

Adatstruktúrák, algoritmusok, objektumok

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

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

III. OOP (objektumok, osztályok)

500. AA Megoldó Alfréd AA 500.

OOP és UML Áttekintés

Objektumorientált Programozás C++ ADATSZERKEZETEK ÉS ALGORITMUSOK 2. GYAKORLAT

Bánsághi Anna 2014 Bánsághi Anna 1 of 31

3. Osztályok II. Programozás II

Globális operátor overloading

Gyakorlati vizsgatevékenység A

Informatikai Kar. 3. fejezet. alapismeretek. Giachetta Roberto

osztályok kapcsolata Származtatatás C++ Izsó Tamás március 19. Izsó Tamás Származtatatás/ 1

PHP II. WEB technológiák. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) PHP II / 19

Objektumorientált programozás C# nyelven II.

Bánsághi Anna 2014 Bánsághi Anna 1 of 68

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

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

C++ programozási nyelv Struktúrák a C++ nyelvben

Bevezetés a programozásba Előadás: Tagfüggvények, osztály, objektum

C# osztálydeníció. Krizsán Zoltán 1. .net C# technológiák tananyag objektum orientált programozás tananyag

OOP #1 (Bevezetés) v :39:00. Eszterházy Károly Főiskola Információtechnológia tsz. Hernyák Zoltán adj.

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Szoftvertechnológia 4. előadás Objektumorientált tervezés: általánosítás Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto

Példa Feladat: Készítsünk egy programot, amelyben különböző geometriai alakzatokat hozhatunk létre (háromszög, négyzet, téglalap, szabályos hatszög), és lekérdezhetjük a területüket, illetve kerületüket. a négy alakzatot négy osztály segítségével ábrázoljuk (Triangle, Square, Rectangle, Hexagon) a háromszöget, négyzetet, hatszöget egy egész számmal (_a), a téglalapot két számmal (_a, _b) reprezentáljuk mindegyik osztálynak biztosítunk lekérdező műveleteket a területre (area) és a kerületre (perimeter) ELTE IK, Szoftvertechnológia 4:2

Példa Tervezés: - _a :int Hexagon + Hexagon(int) + area() :double {query} + perimeter() :int {query} - _a :int - _b :int Rectangle + Rectangle(int, int) + area() :int {query} + perimeter() :int {query} - _a :int Triangle + Triangle(int) + area() :double {query} + perimeter() :int {query} - _a :int Square + Square(int) + area() :int {query} + perimeter() :int {query} ELTE IK, Szoftvertechnológia 4:3

Példa Feladat: Készítsünk egy programot, amelyben egyetemi oktatók, hallgatók és kurzusok adatait tudjuk tárolni. a hallgató (UniversityStudent) és az oktató (UniversityTeacher) rendelkezik névvel, Neptun kóddal és jelszóval, valamint kurzusokkal, a hallgató ezen felül kreditekkel a kurzus (Course) rendelkezik névvel, oktatóval, hallgatókkal, kreditszámmal és maximális létszámmal a kurzus létrehozásakor megkapja az oktatót, amely szintén felveszi azt saját kurzusai közé, míg a hallgató felveheti a kurzust, amennyiben még van szabad hely (ekkor a kurzus megjelenik a hallgatónál, és a hallgató is a kurzusnál) ELTE IK, Szoftvertechnológia 4:4

Példa Tervezés: UniversityTeacher - _name :string - _neptuncode :string - _neptunpassword :string - _courses :vector<course> + UniversityTeacher(string) + name() :string {query} + neptuncode() :string {query} + courses() :vector<course> {query} + newcourse(course) :void -_teacher -_students 0..maxCount() UniversityStudent - _name :string - _neptuncode :string - _neptunpassword :string - _courses :vector<course> + UniversityStudent(string) + name() :string {query} + neptuncode() :string {query} + courses() :vector<course> {query} + newcourse(course) :void + numberofcredits() :int {query} Course -_courses * - _coursename :string - _teacher :UniversityTeacher - _credits :int - _maxcount :int - _students :vector<universitystudent> + Course(string, UniversityTeacher, int, int) + newstudent(universitystudent) :bool + name() :string {query} + teacher() :UniversityTeacher {query} + credits() :int {query} + maxcount() :int {query} + currentcount() :int {query} -_courses * ELTE IK, Szoftvertechnológia 4:5

Kódismétlődés Az objektum-orientált programokban a különböző osztályok felépítése, viselkedése megegyezhet ez kódismétlődéshez vezet, és rontja a kódminőséget Hasonlóan procedurális programozás esetén is előfordulhat kódismétlődés, amely alprogramok bevezetésével kiküszöbölhető objektumorientált programok esetén a működés szorosan összekötött az adatokkal így csak együttesen emelhetőek ki, létrehozva ezzel egy új, általánosabb osztályt, amelyet össze kell kapcsolnunk a jelenlegi, speciálisabb osztállyal ELTE IK, Szoftvertechnológia 4:6

Általánosabb és speciálisabb osztályok Pl.: egyetemi polgár van azonosítója, bejár az egyetemre hallgató tárgyai vannak, vizsgázik oktató kurzusokat tart, vizsgáztat kutató kutatást végez, cikkeket ír ELTE IK, Szoftvertechnológia 4:7

Általánosabb és speciálisabb osztályok Pl.: általánosabb ember egyetemi polgár hallgató programozó speciálisabb tanul, van neve bejár az egyetemre, van azonosítója vizsgázik, vannak tárgyai kockul ELTE IK, Szoftvertechnológia 4:8

Általánosítás Az általánosabb, illetve speciálisabb osztályok között fennálló kapcsolatot nevezzük általánosításnak (generalization) <általános> <speciális> a speciális átveszi az általános összes jellemzőjét (tagok, kapcsolatok), amelyeket tetszőlegesen kibővíthet, vagy újrafogalmazhat az ellentétes irányú relációt nevezzük specializációnak (specialization) Egyetemi polgár Hallgató Oktató Kutató ELTE IK, Szoftvertechnológia 4:9

Általánosítás és specializáció Az általános osztályt ősnek (base, superclass), a speciális osztályt leszármazottnak (descendant, subclass) nevezzük ha csak egy szint a különbség, akkor szülőnek (parent), illetve gyereknek (child) nevezzük egy osztálynak lehet több szülője, ekkor többszörös általánosításról beszélünk Egyetemi polgár nem lehet reflexív, vagy ciklikus Hallgató Oktató nincs multiplicitása, elnevezése, szerepei Demonstrátor ELTE IK, Szoftvertechnológia 4:10

Öröklődés Az általánosítást a programozási nyelvekben az öröklődés (inheritance) technikájával valósítjuk meg, amely lehet specifikációs: csak az általános absztrakt jellemezőit (interfészét) veszi át a speciális implementációs: az osztály absztrakt és konkrét jellemzőit (interfészét és implementációját) veszi át a speciális Öröklődés C++ nyelven: class <osztálynév> : <láthatóság> <ősosztály> { <kiegészítések> }; ELTE IK, Szoftvertechnológia 4:11

Öröklődés Pl.: class SuperClass // általános osztály { public: int value; // mező SuperClass() { value = 1; } // konstruktor void setvalue(int v) { value = v; } int getvalue() { return value; } // metódusok }; SuperClass super; // osztály példányosítása cout << super.value; // 1 super.setvalue(5); cout << super.value; // 5 ELTE IK, Szoftvertechnológia 4:12

Öröklődés Pl.: class SubClass : public SuperClass // speciális osztály, amely megkapja a value, // setvalue(int), getvalue() tagokat { public: int othervalue; SubClass() { value = 2; // használhatjuk az örökölt mezőt othervalue = 3; } void setothervalue(int v) { othervalue = v; } int getothervalue() { return othervalue; } }; ELTE IK, Szoftvertechnológia 4:13

Öröklődés Pl.: SubClass sub; // leszármazott példányosítása // elérhetjük az örökölt tagokat: cout << sub.value; // 2 sub.setvalue(5); cout << sub.value; // 5 // elérhetjük az új tagokat: cout << sub.othervalue; // 3 sub.setothervalue(4); cout << sub.getothervalue(); // 4 ELTE IK, Szoftvertechnológia 4:14

A láthatóság szerepe A tagok láthatósága az öröklődés során is szerepet játszik a látható (public) tagok elérhetőek lesznek a leszármazottban, a rejtett (private) tagok azonban közvetlenül nem ugyanakkor a rejtett tagok is öröklődnek, és közvetetten (örökölt látható műveleteken keresztül) elérhetőek sokszor hasznos, ha a leszármazott osztály közvetlenül elérheti a rejtett tartalmat, ezért használhatunk egy harmadik, védett (protected) láthatóságot az osztályban és leszármazottaiban látható, kívül nem az osztálydiagramban # jelöli ELTE IK, Szoftvertechnológia 4:15

A láthatóság szerepe Pl.: class SuperClass { private: int value; // rejtett mező public: SuperClass() { value = 1; } void setvalue(int v) { value = v; } int getvalue() { return value; } }; SuperClass super; cout << super.getvalue(); // 1 super.setvalue(5); cout << super.getvalue(); // 5 ELTE IK, Szoftvertechnológia 4:16

A láthatóság szerepe Pl.: class SubClass : public SuperClass { // a value már nem látszódik, de öröklődik private: int othervalue; public: SubClass() { setvalue(2); // nem látja a value mezőt, de // közvetetten használhatja othervalue = 3; } }; ELTE IK, Szoftvertechnológia 4:17

A láthatóság szerepe Pl.: SubClass sub; // leszármazott példányosítása // elérhetjük az örökölt tagokat: cout << sub.getvalue(); // 2 sub.setvalue(5); cout << sub.getvalue(); // 5 // elérhetjük az új tagokat: cout << sub.getothervalue(); // 3 sub.setothervalue(4); cout << sub.getothervalue(); // 4 ELTE IK, Szoftvertechnológia 4:18

A láthatóság szerepe Pl.: class SuperClass { protected: int value; // védett mező public: SuperClass() { value = 1; } void setvalue(int v) { value = v; } int getvalue() { return value; } }; SuperClass sup; cout << sup.getvalue(); // 1 sup.setvalue(5); cout << sup.getvalue(); // 5 ELTE IK, Szoftvertechnológia 4:19

A láthatóság szerepe Pl.: class SubClass : public SuperClass { // minden elérhető lesz az ősből private: int othervalue; public: SubClass() { value = 2; // használhatjuk az örökölt mezőt othervalue = 3; } }; ELTE IK, Szoftvertechnológia 4:20

Öröklődés Feladat: Készítsünk egy programot, amelyben különböző geometriai alakzatokat hozhatunk létre (háromszög, négyzet, téglalap, szabályos hatszög), és lekérdezhetjük a területüket, illetve kerületüket. javítsunk a korábbi megoldáson öröklődés segítségével kiemelünk egy általános alakzat osztályt (Shape), amelybe helyezzük a közös adatot (_a), ennek védett (protected) láthatóságot adunk a többi osztályban csak az öröklődést jelezzük, a működés nem változik (továbbra is a konstruktorok állítják be _a értékét) ELTE IK, Szoftvertechnológia 4:21

Öröklődés Tervezés: Shape # _a :int Hexagon Rectangle Square Triangle + Area() :double {query} + Hexagon(int) + Perimeter() :int {query} - _b :int + Area() :int {query} + Perimeter() :int {query} + Rectangle(int, int) + Area() :int {query} + Perimeter() :int {query} + Square(int) + Area() :double {query} + Perimeter() :int {query} + Triangle(int) ELTE IK, Szoftvertechnológia 4:22

Öröklődés Megvalósítás: class Shape { protected: int _a; }; class Ractangle : public Shape { private: int _b; public: Rectangle(int a, int b) { _a = a; _b = b; } }; ELTE IK, Szoftvertechnológia 4:23

Metódusok viselkedése Öröklődés során lehetőségünk van a viselkedés újrafogalmazására a leszármazottban az ősével megegyező szintaktikájú metódusok vagy elrejtik, vagy felüldefiniálják az örökölt metódusokat a leszármazott példányosításakor az ott definiált viselkedés érvényesül Öröklődés során a leszármazott osztály példányosításakor az ős is példányosodik a konstruktor is öröklődik, és meghívódik a leszármazott példányosításakor (implicit, vagy explicit) a destruktor is öröklődik, és automatikusan meghívódik a leszármazott megsemmisítésekor ELTE IK, Szoftvertechnológia 4:24

Metódusok viselkedése Pl.: class SuperClass { int getdefaultvalue() { return 1; } int computedoubledefault() { return 2 * getdefaultvalue(); // felhasználjuk a másik metódust } }; Superclass super; cout << sub.computedoubledefault(); // kiírja: 2 ELTE IK, Szoftvertechnológia 4:25

Metódusok viselkedése class SubClass : public SuperClass { int getdefaultvalue() { return 2; } // elrejtő metódus }; SubClass sub; cout << sub.computedoubledefault(); // kiírja: 4, mivel getdefaultvalue() == 2 ELTE IK, Szoftvertechnológia 4:26

Metódusok viselkedése Feladat: Készítsünk egy programot, amelyben különböző geometriai alakzatokat hozhatunk létre (háromszög, négyzet, téglalap, szabályos hatszög), és lekérdezhetjük a területüket, illetve kerületüket. az ősben létrehozzuk a terület (area), illetve kerület (perimeter) lekérdezés metódusait, amelyeket felüldefiniálunk a leszármazottakban, így jobban kifejezzük, hogy minden alakzat rendelkezik ilyen művelettel bővíthetjük az ős konstruktorának feladatkörét a közös adat (_a) inicializálásával, így minden osztály a saját mezőinek inicializálását végzi ELTE IK, Szoftvertechnológia 4:27

Metódusok viselkedése Tervezés: # _a :int Shape + Shape(int) + area() :double {query} + perimeter() :int {query} Hexagon Rectangle Square Triangle + Hexagon(int) + area() :double {query} + perimeter() :int {query} - _b :int + Rectangle(int, int) + area() :int {query} + perimeter() :int {query} + Square(int) + area() :int {query} + perimeter() :int {query} + Triangle(int) + area() :double {query} + perimeter() :int {query} ELTE IK, Szoftvertechnológia 4:28

Metódusok viselkedése Megvalósítás: class Shape { protected: int _a; public: Shape(int a) { _a = a; } double area() const { return 0; } double perimeter() const { return 0; } // alapértelmezett viselkedés, ami // öröklődik }; ELTE IK, Szoftvertechnológia 4:29

Metódusok viselkedése Megvalósítás: class Rectangle : public Shape { private: int _b; public: Rectangle(int a, int b) : Shape(a) { _b = b; } double area() const { return _a * _b; } double perimeter() const { return 2 * (_a + _b); } // elrejtő viselkedés }; ELTE IK, Szoftvertechnológia 4:30

Polimorfizmus Mivel a leszármazott példányosításakor egyúttal az ősből is létrehozunk egy példányt, a keletkezett objektum példánya lesz mindkét típusnak a leszármazott objektum bárhova behelyettesíthető lesz, ahol az ős egy példányát használjuk Ezt a jelenséget (altípusos) polimorfizmusnak (polymorphism, subtyping), vagy többalakúságnak nevezzük pl. a SubClass sub; utasítással egyúttal a SuperClass példányát is elkészítjük öröklődés nélkül is fennállhat dinamikus típusrendszerű programozási nyelvekben (ez a strukturális polimorfizmus) ELTE IK, Szoftvertechnológia 4:31

Polimorfizmus A programozási nyelvek az objektumokat általában dinamikusan kezelik (referencián, vagy mutatón keresztül) pl.: SuperClass* super = new SuperClass(); cout << super->getvalue(); // 1 A polimorfizmus lehetővé teszi, hogy a dinamikusan létrehozott objektumra hivatkozzunk az ősosztály segítségével pl.: SuperClass* super = new SubClass(); // a mutató az ősosztályé, de ténylegesen // a leszármazott objektummal dolgozunk cout << super->getvalue(); // 2 ELTE IK, Szoftvertechnológia 4:32

Polimorfizmus A dinamikusan létrehozott objektumot így két típussal rendelkeznek: a hivatkozás osztálya az objektum statikus típusa, ezt értelmezi a fordítóprogram, ennek megfelelő tagokat hívhatunk meg a példányosított osztály a változó dinamikus típusa, futás közben az annak megfelelő viselkedést végzi Pl.: SuperClass* super1 = new SubClass(); // super1 statikus típusa SuperClass, // dinamikus típusa SubClass SuperClass* super2 = new SuperClass(); // itt egyeznek a típusok ELTE IK, Szoftvertechnológia 4:33

Polimorfizmus A dinamikus típus futás közben változtatható, mivel az ős típusú hivatkozásra tetszőleges leszármazott példányosítható pl.: SuperClass* super = new SuperClass(); cout << super->getvalue(); // 1 delete super; super = new SubClass(); cout << super->getvalue(); // 2 ugyanakkor a statikus típusra korlátozott az elérhető tagok köre, pl.: cout << super->getothervalue(); // fordítási hiba, a statikus típusnak nincs // getothervalue() művelete ELTE IK, Szoftvertechnológia 4:34

Polimorfizmus A polimorfizmus azt is lehetővé teszi, hogy egy gyűjteményben különböző típusú elemeket tároljunk a gyűjtemény elemtípusa az ős hivatkozása lesz, és az elemek dinamikus típusát tetszőlegesen váltogathatjuk Pl.: SuperClass* array[3]; array[0] = new SuperClass(); array[1] = new SubClass(); array[2] = new SubClass(); for (int i = 0; i < 3; i++) cout << array[i]->getvalue(); // 1 2 2 ELTE IK, Szoftvertechnológia 4:35

Dinamikus kötés Dinamikus példányosítást használva a program a dinamikus típusnak megfelelő viselkedést rendeli hozzá az objektumhoz futási idő alatt, ezt dinamikus kötésnek (dynamic binding) nevezzük amennyiben felüldefiniálunk (override) egy műveletet, a dinamikus típusnak megfelelő végrehajtás fog lefutni ehhez azonban a műveletnek engedélyeznie kell a felüldefiniálást, ekkor beszélünk virtuális (virtual) műveletről a nem virtuális műveletek a lezárt, vagy véglegesített (sealed) műveletek, ezeket csak elrejteni lehet, és ekkor a statikus típus szerint fog végrehajtódni a művelet ELTE IK, Szoftvertechnológia 4:36

Dinamikus kötés Pl.: class SuperClass { protected: int value; public: SuperClass() { value = 1; } void setvalue(int v) { value = v; } }; virtual void getvalue() { return value; } // virtuális metódus void getdefaultvalue() { return 1; } // véglegesített metódus ELTE IK, Szoftvertechnológia 4:37

Dinamikus kötés class SubClass : public SuperClass { void getvalue() { return othervalue; } // felüldefináló metódus void getdefaultvalue() { return 2; } // elrejtő metódus }; SuperClass *sup = new SuperClass(); cout << sup->getvalue(); // 1 cout << sup->getdefaultvalue(); // 1 sup = new SubClass(); cout << sup->getvalue(); // 3 cout << sup->getdefaultvalue(); // 1 ELTE IK, Szoftvertechnológia 4:38

Dinamikus kötés Feladat: Készítsünk egy programot, amelyben különböző geometriai alakzatokat hozhatunk létre (háromszög, négyzet, téglalap, szabályos hatszög), és lekérdezhetjük a területüket, illetve kerületüket. Az alakzatokat csoportosíthatjuk is. az ősben a terület (area), illetve kerület (perimeter) lekérdezés metódusait virtuálissá változtatjuk, így már felüldefiniáljuk őket a leszármazottban létrehozzuk az alakzatok csoportját (Group), amelybe behelyezzük az alakzatok gyűjteményét lekérdezhetjük a csoportba lévő elemek összterületét és összkerületét ELTE IK, Szoftvertechnológia 4:39

Dinamikus kötés Tervezés: Group - _shapes :Shape[] + addshape(shape) :void + removeshape(shape) :void + area() :double {query} + perimeter() :int {query} -_shapes * # _a :int Shape + Shape(int) + area() :double {query} + perimeter() :int {query} Hexagon Rectangle Square Triangle + Hexagon(int) + area() :double {query} + perimeter() :int {query} - _b :int + Rectangle(int, int) + area() :int {query} + perimeter() :int {query} + Square(int) + area() :int {query} + perimeter() :int {query} + Triangle(int) + area() :double {query} + perimeter() :int {query} ELTE IK, Szoftvertechnológia 4:40

Dinamikus kötés Megvalósítás: class Shape { protected: int _a; public: Shape(int a) { _a = a; } virtual double area() const { return 0; } virtual double perimeter() const { return 0; } // alapértelmezett viselkedés, ami // öröklődik, de felüldefiniálható }; ELTE IK, Szoftvertechnológia 4:41

Dinamikus kötés Megvalósítás: class Group { private: vector<shape*> _shapes; public: double area() const { double sum = 0; for (int i = 0; i < _shapes.size(); i++) sum += _shapes[i]->area(); // a megfelelő metódus fut le return sum; } }; ELTE IK, Szoftvertechnológia 4:42

Absztrakt osztályok Amennyiben egy ősosztály olyan általános viselkedéssel rendelkezik, amelyet konkrétan nem tudunk alkalmazni, vagy általánosságban nem tudunk jól definiálni, akkor megtilthatjuk az osztály példányosítását A nem példányosítható osztályt absztrakt osztálynak (abstract class) nevezzük csak statikus típusként szerepelhetnek absztrakt osztályban létrehozható olyan művelet, amelynek nincs megvalósítása, csak szintaxisa, ezek az absztrakt, vagy tisztán virtuális műveletek a leszármazottak megvalósítják (realize) az absztrakt műveletet (vagy szintén absztrakt osztályok lesznek) ELTE IK, Szoftvertechnológia 4:43

Absztrakt osztályok absztrakt osztály létrehozható a konstruktor elrejtésével, vagy absztrakt művelet definiálásával a diagramban dőlt betűvel jelöljük őket Pl.: class SuperClass { // absztrakt osztály virtual void getvalue() =0; // absztrakt metódus }; SuperClass *super = new SubClass(); cout << super.getvalue(); // 3 super = new SuperClass(); // fordítási hiba ELTE IK, Szoftvertechnológia 4:44

Absztrakt osztályok Feladat: Készítsünk egy programot, amelyben egyetemi oktatók, hallgatók és kurzusok adatait tudjuk tárolni. a hallgató (UniversityStudent) és az oktató (UniversityTeacher) közös tagjait kiemeljük az egyetemi polgár (UniversityCitizen) absztrakt ősosztályba a leszármazottak definiálják a newcourse( ) műveletet különkülön, ezért az ősben tisztán absztrakt lesz, továbbá a hallgatónál megjelenik a kreditek lekérdezése (numberofcredits()) a változtatás a kurzus (Course) osztályra nincs hatással ELTE IK, Szoftvertechnológia 4:45

Absztrakt osztályok Tervezés: UniversityCitizen # _name :string # _neptuncode :string # _neptunpassword :string # _courses :vector<course> # UniversityCitizen(string) + name() :string {query} + neptuncode() :string {query} + courses() :vector<course> {query} + newcourse(course) :void UniversityStudent + UniversityStudent(string) + numberofcredits() :int {query} + newcourse(course) :void -_students * UniversityTeacher + UniversityTeacher(string) + newcourse(course) :void -_teacher -_courses * Course - _coursename :string - _teacher :UniversityTeacher - _credits :int - _maxheadcount :int - _students :vector<universitystudent> + Course(string, UniversityTeacher, int, int) + newstudent(universitystudent) :bool + name() :string {query} + teacher() :UniversityTeacher* {query} + credits() :int {query} + maxcount() :int {query} + currentcount() :int {query} ELTE IK, Szoftvertechnológia 4:46

Absztrakt osztályok Megvalósítás: class UniversityCitizen { // absztrakt osztály public: virtual void newcourse(course& course) = 0; // absztrakt művelet }; class UniversityStudent : public UniversityCitizen { public: void newcourse(const Course& course) { } }; ELTE IK, Szoftvertechnológia 4:47

Interfészek Amennyiben csak a felületét akarjuk az osztályoknak definiálni, lehetőségünk van interfészek (interface) létrehozására egy olyan absztrakt osztályt, amely csak publikus absztrakt műveletekből áll célja a különböző feladatkörök elválasztása, a többszörös öröklődés megkönnyítése a diagramban az <<interface>> csoportot használjuk, és elhagyjuk a dőlt betűket «interface» <interfésznév> + <metódus> () :<típus> <osztálynév> + <metódus> () :<típus> Amennyiben interfészt specializálunk osztályba, azzal megvalósítjuk (realize, implement) az interfészt ELTE IK, Szoftvertechnológia 4:48

Interfészek Feladat: Készítsünk egy programot, amelyben különböző geometriai alakzatokat hozhatunk létre (háromszög, négyzet, téglalap, szabályos hatszög), és lekérdezhetjük a területüket, illetve kerületüket. Az alakzatokat csoportosíthatjuk is. az egységes kezelés érdekében létrehozhatjuk a síkbeli elemek (Planar) interfészét, amely definiálja, hogy minden síkbeli elemnek van területe és kerülete a síkbeli elemet megvalósítja a csoport és az alakzat is az alakzat lehet absztrakt osztály (a konstruktorát védetté tehetjük) ELTE IK, Szoftvertechnológia 4:49

Interfészek Tervezés: «interface» Planar + area() :double {query} + perimeter() :int {query} Group - _shapes :Shape[] + addshape(shape) :void + removeshape(shape) :void + area() :double {query} + perimeter() :int {query} -_shapes * # _a :int Shape # Shape(int) + area() :double {query} + perimeter() :int {query} Hexagon Rectangle Square Triangle + Hexagon(int) + area() :double {query} + perimeter() :int {query} - _b :int + Rectangle(int, int) + area() :int {query} + perimeter() :int {query} + Square(int) + area() :int {query} + perimeter() :int {query} + Triangle(int) + area() :double {query} + perimeter() :int {query} ELTE IK, Szoftvertechnológia 4:50

Interfészek Megvalósítás: class Planar { // interfész public: virtual double area() const = 0; virtual double perimeter() const = 0; // csak absztrakt műveleteket tartalmaz }; class Shape : public Planar { protected: int _a; Shape(int a) { _a = a; } }; ELTE IK, Szoftvertechnológia 4:51