OO modellezés fogalmai újból
Programozás alapjai II. (5. ea) C++
• Objektum – adat (állapot) és a rajta végezhető művelet – a világ egy részének egy olyan modellje, amely külső üzenetekre reagálva valahogyan viselkedik (változtatja az állapotát, újabb üzenetet küld) – üzenetekre (message), vagy eseményekre (event) a metódus végrehajtásával reagál, viselkedik (behavior) – polimorf működés
analitikus és korlátozó öröklés Szeberényi Imre BME IIT
<
[email protected]>
MŰEGYTEM 1782 C++ programozási nyelv
© BME-IIT Sz.I.
2011.03.8.
-1C++ programozási nyelv © BME-IIT Sz.I.
OO modellezés fogalmai újból/2
2011.03.8.
-2-
Osztály és példány jelölése
• Objektum osztály, osztály (class) – megegyező viselkedésű és struktúrájú objektumok mintája, gyártási forrása. (pl, ház, ablak, kutya)
Kutya
(Kutya) Blöki
Kutya
(Kutya) Blöki korcs 2
(Kutya)
• Objektum példány, objektum (instance) – Minden objektum önállóan, létező egyed (Blöki, Morzsi, Bikfic)
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
név: string fajta: string kor: int
-3-
Osztály és típus
2011.03.8.
-4-
Osztály és típus/2
• int i;
• Példaként vegyünk egy olyan komplex objektumot, amiben valós és képzetes résszel tárolunk, és vegyünk egy másikat polárkoordinátákkal. • A kétfajta komplex megvalósítás osztály szinten különböző, de típusuk – viselkedésük – interfész szinten azonos. • Hagyományos nyelveken a típus értékhalmazt jelöl.
– i nevű objektum aminek a mintája int
• Nem teljesen azonos, mert a típus egy objektum-halmaz viselkedését specifikálja. • Az osztály a típus által meghatározott viselkedést implementálja. • Egy adott objektumtípust többféleképpen lehet implementálni, (több osztállyal).
C++ programozási nyelv © BME-IIT Sz.I.
C++ programozási nyelv © BME-IIT Sz.I.
(Kutya) Morzsi puli 3
2011.03.8.
-5-
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
-6-
Modellezés objektumokkal
Modellezés eszközei, módszertana
• Különböző szempontok szerint modellezünk. • Objektummodell – Adat szempontjából írja le a rendszer statikus tulajdonságait (osztály v. entitás-relációs diagram).
• Részletesen szoftvertechnológiája c. tárgyban a következő félévben. • Itt csak minimális alapok a nyelvi eszközök megismeréséhez.
• Dinamikus modell – A működés időbeliségét rögzíti (állapotgráf, kommunikációs diagram).
• Funkcionális modell – Funkció szerint ír le (adatfolyam-ábra). C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
-7-
Objektummodell
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
-8-
Példák a kapcsolatok leírására
• Attribútumok leírása – Elnevezés típusú attribútumok. Nem vagy ritkán változnak (név, személyi szám, nem) – Leíró attribútumok. – Referenciák. Kimutatnak az objektumból.
Ember név sz. idő cím
• Kapcsolatok (relációk) leírása – láncolás – objektum példányok között – asszociáció – osztályok közötti kapcsolat
2011.03.8.
-9-
Egy – több kapcsolat
név sz. idő cím
szült
1..*
2011.03.8.
Hallgató név sz. idő cím
név sz. idő nem
- 10 -
2011.03.8.
1..*
vizsgázik
Tárgy 1..* név
előadó hely
vizsgajegy
Egy tárgyból többen is vizsgázhatnak. Egy hallgató több tárgyból is vizsgázhat. A vizsga eredménye (attribútuma) a vizsgajegy.
Egy anya legalább egy gyereket szült (1..*). Egy gyereket pontosan egy anya szült.
C++ programozási nyelv © BME-IIT Sz.I.
C++ programozási nyelv © BME-IIT Sz.I.
Kapcsolatok attribútumai
Gyerek
Anya
* név fajta kor
Egy ember 0 vagy több kutyának lehet gazdája. Egy kutyának legfeljebb egy gazdája van, de lehet, hogy gazdátlan.
• Öröklés leírása C++ programozási nyelv © BME-IIT Sz.I.
Kutya
gazda
0..1
- 11 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 12 -
Komponens reláció
* Bekezdés
Levél
Öröklés • Az öröklés olyan implementációs és modellezési eszköz, amelyik lehetővé teszi, hogy egy osztályból olyan újabb osztályokat származtassunk, melyek rendelkeznek az eredeti osztályban már definiált tulajdonságokkal, szerkezettel és viselkedéssel. • Újrafelhasználhatóság szinonimája. • Nem csak bővíthető, hanem a tagfüggvények át is definiálhatók.
* Karakter
A karakter része a bekezdésnek, a bekezdés része a levélnek. Elnevezés: szülő – gyerek viszony, de nem keverendő össze az örökléssel!
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 13 -
C++ programozási nyelv © BME-IIT Sz.I.
Feladat
– Diák attribútumai: név, sz. idő, átlag, évfolyam – Tanár attribútumai: név, sz. idő, tantárgy, fizetés
Ember név sz. idő
“az egy” Diák
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 15 -
általánosítás “az egy” Tanár
+átlag +évf.
– név, sz. idő 2x, műveletek 2x, nehezen módosítható
+tantárgy +fizetés
származtatott osztályok C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 16 -
2011.03.8.
- 18 -
C++ jelölés
Öröklés másként jelölve
class Ember { String *nev; Date szIdo; public: Ember(); void setDate(Date d); void setName(char *n); const char *getName(); ... };
Ember név sz. idő
C++ programozási nyelv © BME-IIT Sz.I.
alaposztály specializáció
• Milyen osztályokat hozzunk létre ? • 2 független osztály ?
Diák
- 14 -
Örökléssel
• Diákokból, tanárokból álló rendszert szeretnénk modellezni.
+átlag +évf.
2011.03.8.
Tanár +tantárgy +fizetés 2011.03.8.
- 17 -
C++ programozási nyelv © BME-IIT Sz.I.
C++ jelölés/2 class Diak :public Ember { double atlag; public: Diak(); void setAv(double a); .... }; class Tanar :public Ember { double fizetes; public: Tanar(); .... };
Öröklés előnyei
Alaposztályból minden látszik ami publikus
• Hasonlóság kiaknázása
+Új attribútum
• Módosíthatóság mellékhatások nélkül
– Világosabb programstruktúra – Újabb tulajdonságok hozzáadása
• Kiterjeszthetőség
+Új tagfüggvény
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
– Újrafelhasználható
- 19 -
Öröklés fajtái
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
Analitikus és korlátozó öröklés
I. • Analitikus • Korlátozó
Alakzat poz, szin mozgat() Vonal +végpont +rajzol()
II. • Egyszerű • Többszörös
Kör +sugár +rajzol()
analitikus öröklés
Téglalap +csúcs +rajzol()
korlátozó öröklés
Négyzet
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 21 -
Többszörös öröklés
2011.03.8.
- 22 -
• A típusú objektum kompatibils B-vel, ha A típusú objektum bárhol és bármikor alkalmazható, ahol B használata megengedett. • A reláció reflektív és tranzitív, de nem szimmetrikus. • A kompatibilitás egy hierarchiát szab meg
Ideigl. alk. idő
Ideigl.csopvez.
C++ programozási nyelv © BME-IIT Sz.I.
C++ programozási nyelv © BME-IIT Sz.I.
Kompatibilitás és öröklés
Alkalmazott név, fizetés
Csoportvez. csoport
- 20 -
– pl: állat <-komp.- madár <-komp.- veréb
2011.03.8.
- 23 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 24 -
Kompatibilitás/2 specializáció (altípus) madár
galamb
veréb
állat
Geometria alakzatok C++ban
vízi
emlős
kutya
Alakzat poz, szin mozgat()
általánosítás (szupertípus)
bálna
C++ programozási nyelv © BME-IIT Sz.I.
Vonal +végpont +rajzol() ponty
2011.03.8.
- 25 -
Alakzat alaposztály
Négyzet
C++ programozási nyelv © BME-IIT Sz.I.
korlátozó öröklés
2011.03.8.
- 26 -
class Vonal : public Alakzat { Alaposztályból minden int xv, yv; látszik ami publikus public: Vonal(int x1, int y1, int x2, int y2, int sz) : Alakzat(x1, y1, sz), xv(x2), yv(y2) { } void rajzol( ); void mozgat(int dx, int dy); };
2011.03.8.
- 27 -
Vonal tagfüggvényei
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 28 -
Téglalap osztály
void Vonal :: Rajzol( ) { .... // vonalat rajzol }
class Teglalap : public Alakzat { int xc, yc; public: Teglalap(int x1, int y1, int x2, int y2, int sz) : Alakzat(x1, y1, sz), xc(x2), yc(y2) { } void rajzol( ); void mozgat(int dx, int dy); };
void Vonal :: Mozgat( int dx, int dy ) { int sz = szin; // tényleges rajzolási szín elmentése szin = BACKGRD;// rajzolási szín legyen a háttér színe rajzol( ); // A vonal letörlése az eredeti helyről x += dx; y += dy; // mozgatás: a pozíció változik szin = sz; // rajzolási szín a tényleges szín rajzol( ); // A vonal felrajzolása az új pozícióra } C++ programozási nyelv © BME-IIT Sz.I.
Téglalap +csúcs +rajzol()
Vonal osztály
class Alakzat { Védelem enyhítése a protected: leszármazottak felé int x, y; int szin; public: Alakzat(int x0, int y0, int sz) :x(x0), y(y0), szin(sz) { } // mozgat(), érezzük, hogy itt a helye, de nem // tudjuk hogyan kell rajzolni! // Ezért próbáljuk a származtatottba tenni, ahol // már ismert a rajzolás menete. }; C++ programozási nyelv © BME-IIT Sz.I.
Kör +sugár +rajzol()
analitikus öröklés
2011.03.8.
Ugyanaz, mint a vonalnál, csak a hívott rajzol() más - 29 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 30 -
mozgat() helye
Alakzat osztály virtuális függvénnyel class Alakzat { Az öröklés során újabb protected: jelentést kaphat, ami az int x, y; alaposztályból is elérhető, int szin; így a mozgat()-ból is. public: Alakzat(int x0, int y0, int sz) :x(x0), y(y0), szin(sz) { } virtual void rajzol( ) { } void mozgat(int dx, int dy); }; Most már ide tehetjük,
• Származtatott osztályokban – látszólag ugyanaz a függvény minden alakzatban – csak az általa hívott rajzol() más
• Alaposztályban – ha a hívott rajzol()-t egy manó le tudná cserélni mindig a megfelelő származtatott rajzol()-ra, akkor működne Æ virtuális függvény
mert a rajzol() is itt van. C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 31 -
Alakzat mozgat() tagfüggvénye
2011.03.8.
2011.03.8.
class Vonal : public Alakzat { int xv, yv; public: Vonal(int x1, int y1, int x2, int y2, int sz) : Alakzat(x1, y1, sz), xv(x2), yv(y2) { } void rajzol( ); // átdefiniáljuk a virt. fv-t. void mozgat(int dx, int dy); }; void Vonal::rajzol( ) { .... // vonalat rajzol. // Az alaposztályból hívva is ez hívódik } - 33 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
Téglalap osztály újra
Mintaprogram
class Teglalap : public Alakzat { int xc, yc; public: Teglalap(int x1, int y1, int x2, int y2, int sz) : Alakzat(x1, y1, sz), xc(x2), yc(y2) { } void rajzol( ); // átdefiniáljuk a virt. fv-t. void mozgat(int dx, int dy); }; void Teglalap::rajzol( ) { .... // téglalapot rajzol. // Az alaposztályból hívva is ez hívódik }
main ( ) { Teglalap tegla(1, 10, 2, 40, RED); // téglalap Vonal vonal(3, 6, 80, 40, BLUE); // vonal Alakzat alak(3, 4, GREEN); // ??? alak.mozgat(3, 4); // 2 db rajzol() hívás vonal.rajzol( ); // 1 db rajzol() vonal.mozgat(10, 10); // 2 db rajzol() hívás Alakzat *ap[10]; ap[0] = &vonal; // nem kell típuskonverzió ap[1] = &tegla; for (int i = 0; i < 2; i++ ) ap[i] ->rajzol(); }
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 32 -
Vonal osztály újra
void Alakzat :: Mozgat( int dx, int dy ) { int sz = szin; // tényleges rajzolási szín elmentése szin = BACKGRD;// rajzolási szín legyen a háttér színe rajzol( ); // A vonal letörlés az eredeti helyről x += dx; y += dy; // mozgatás: a pozíció változik szin = sz; // rajzolási szín a tényleges szín rajzol( ); // A vonal felrajzolása az új pozícióra }
C++ programozási nyelv © BME-IIT Sz.I.
C++ programozási nyelv © BME-IIT Sz.I.
- 35 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 34 -
- 36 -
Mikor melyik rajzol() ?
Alakzat önállóan ?
Virtuális Alakzat:: rajzol() Alakzat::rajzol() Vonal::rajzol() Vonal::rajzol()
Nem virtualis Alakzat:: rajzol() Alakzat::rajzol() Vonal::rajzol() Alakzat::rajzol()
sp[0]->rajzol() Vonal::rajzol() Vonal-ra mutat sp[1]->rajzol() Teglalap::rajzol() Teglalap-ra mutat
Alakzat::rajzol()
alak.mozgat() vonal.rajzol() vonal.mozgat
Alakzat::rajzol()
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 37 -
Absztrakt alaposztályok
Vonal xv, yv rajzol( )
C++ programozási nyelv © BME-IIT Sz.I.
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 38 -
2011.03.8.
C struktúrák struct Alakzat x y szín
Alakzat x, y, szín mozgat( ) Vonal xv, yv rajzol( )
- 39 -
Öröklés impl., ha a Rajzol() virtuális
Alakzat x, y, szín rajzol( )
// Mit rajzol ??
• Nem értelmes példányosítani, de lehet, mivel osztály. • Nyelvi eszközzel tiltjuk: Absztrakt alaposztály
C++ osztályok
class Alakzat { Nem protected: int x, y, szin; példányosítható public: Alakzat( int x0, int y0, int sz) ; void mozgat( int dx, int dy ); virtual void rajzol( ) = 0; // tisztán virtuális };
C++ osztályok
alak.mozgat(3, 4);
Öröklés impl., ha nincs virtuális fv.
• Csak az öröklési hierarchia kialakításában vesznek részt, nem példányosodnak • A virtuális függvényeknek nincs értelmes törzse: tisztán (pure) virtuális függvény
C++ programozási nyelv © BME-IIT Sz.I.
Alakzat alak(3, 4, GREEN); // ???
Új rész
C++ programozási nyelv © BME-IIT Sz.I.
struct Vonal x y szín xv yv
C globális függvények AlakzatMozgat( ) VonalRajzol( ) AlakzatKonstr( ) VonalKonstr( ) 2011.03.8.
- 40 -
Alakzat C implementációja
C struktúrák
struct Alakzat { int x, y, szín; void (*Rajzol)( ); };
struct Alakzat x y szín
struct Vonal x y szín
&rajzol()
&rajzol()
void AlakzatMozgat( struct Alakzat *this ) { } AlakzatKonstr(struct Alakzat *this, int x0, int y0, int sz) { this->rajzol = AlakzatRajzol; // fordító !!! this->x = x0; this->y = y0; this->szin = sz; }
xv yv
C globális függvények AlakzatRajzol( ) VonalRajzol( ) AlakzatKonstr( ) VonalKonstr( ) 2011.03.8.
- 41 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 42 -
Alakzat C implementációja/2
Téglalap osztály újra
void AlakzatMozgat(struct Alakzat *this, int dx, int dy ) { int sz = this->szin; this->szin = BACKGRD; (*(this->rajzol))(this); this->x += dx; this->y += dy; this->szin = sz; (*(this ->rajzol))(this); }
class Teglalap : public Alakzat { int xc, yc; public: Teglalap(int x1, int y1, int x2, int y2, int sz) : Alakzat(x1, y1, sz), xc(x2), yc(y2) { } void ujMeret(int x2, int y2) { xc = x + x2; yc = y + y2; } void rajzol( ); // mozgat() az alaposztályban };
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 43 -
– Attribútumok – Kapcsolatok (relációk)
• Öröklés (specializáció ÅÆ általánosítás) – analitikus v. korlátozó – egyszerű v. többszörös
• C++ nyelvi eszköz: – analitikus Æ public, korlátozó Æ private – tagfüggvények átdefiniálása, protected mezők – virtuális tagfüggvény: alaposztály felől elérhető a származtatott osztály tagfüggvénye, – absztrakt alaposztály nem példányosítható
Az ujMeret() fv-t így kívülről elérhetetlenné tettük (korlátoztuk az elérését) - 45 -
Védelem összefoglalása külső public:
√
protected: private:
C++ programozási nyelv © BME-IIT Sz.I.
származtatott tagfüggvény és barát
√
√
√
√ √
2011.03.8.
- 44 -
• Objektummodell
class Negyzet : private Teglalap { public: Eltakarja az alaposztályt Negyzet(int x1, int y1, int s, int sz) : Teglalap(x1, y1, x1+s, y1+s, sz) { } void rajzol( ) { Teglalap::rajzol(); } void mozgat(int dx, int dy) { Teglalap::mozgat(dx, dy); } };
2011.03.8.
2011.03.8.
Összefoglalás
Négyzet osztály (korlátoz)
C++ programozási nyelv © BME-IIT Sz.I.
C++ programozási nyelv © BME-IIT Sz.I.
- 47 -
C++ programozási nyelv © BME-IIT Sz.I.
2011.03.8.
- 46 -