Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Absztrakció


      Az 1990-es évek óta az objektum-orientált programozási stílus előtérbe
került a strukturált programozással szemben. A strukturált program adatból és
algoritmusból épül fel, míg az objektum-orientált program emellett absztrakciót
is végez. Az absztrakció az objektumok révén valósul meg, melyek
leegyszerűsítik az adatok és algoritmusok kezelését. Az objektumokat
tulajdonságaik alapján osztályozni lehet, az adott osztályhoz tartozó
objektum pedig az osztály példányának tekinthető.





1. Osztályok és objektumok


2. Öröklés


3. Struktúrák


4. Osztályok


5. Kódrendezés


6. Konstruktorok és destruktorok


7. Objektumok másolása


8. Konstans objektumok és konstans tagfüggvények


9. Osztályok illesztése


10. Friend függvények és friend osztályok


11. A this mutató


12. Az osztályok statikus tagjai


13. Proxy osztályok









1. Osztályok és objektumok


     
Példaképp adott egy négyzethálós kép. Minden négyzet egy objektum,
melynek van egy pozíciója és egy színe. Ezzel a két adattal művelet hajtható
végre, például megváltoztatható a szín vagy újra rajzolható a négyzet. Mivel minden négyzetnek
van színe és pozíciója, ezért egy osztályba sorolható, a Négyzet osztályba.










A Négyzet osztály létrehozása egy adattípus létrehozásával ér fel, mert lehetővé teszi a Négyzet típusú változók deklarálását. Ezeket a változókat a Négyzet osztály objektumainak hívjuk. Például a
Négyzet obj  utasítás az obj objektumot deklarálja, amely Négyzet típusú, és rendelkezik a szín és pozíció tagváltozókkal és a Színez, Rajzol tagfüggvényekkel.









2. Öröklés


      Nem csak négyzetek, hanem háromszögek is részesei lehetnek a képnek.
Ezeknek ugyanazok a tulajdonságai vannak és
ugyanazok a műveletek végezhetőek el velük, de mégsem teljesen ugyanazok, mert például az újrarajzoló algoritmus
más. Továbbá beiktatható egy új tulajdonság ami méginkább megkülünbözteti a háromszöget a négyzettől: a csúcsok
száma.









A hasonlóságok miatt ezt a két osztályt egy felsőbb absztrakciós szinten közös osztályba lehet sorolni: a Formák osztályba.









A Formák
osztály még absztraktabb a Négyzet és
Háromszög osztályoknál, mert
méginkább kiiktatja a kevésbé fontos információkat. Nem foglalkozik azzal, hogy
a forma négyzet-e vagy háromszög, az majd lentebb eldől. Magába foglalja a
közös tulajdonságokat, így ezeket nem kell külön deklarálni mindenik alsó
osztályban. Az alsó osztályok (Négyzet és
Háromszög) megöröklik a Formák tulajdonságait. Ami nem egyforma
azt felülírja mindenik a maga osztályában (például a
csúcs tagváltozót és a Rajzol tagfüggvényt). A Négyzet és a Háromszög
osztályok származtatott (vagy derivált) osztályai a Formák
osztálynak. A Formák osztály a
származtatott osztályok ősosztálya (vagy alaposztálya). Az öröklődés célja, hogy közös
tulajdonságok általánosabbá váljanak kezelhetőbbé téve az
információt.













3. Struktúrák


     
A hagyományos strukturált programozási nyelv a C. A Pascal, a Deplphi és
a C++ csupán támogatják az objektum-orientált módszereket, azonban alapjában
ezek is strukturált programozási nyelvek. Tisztán objektum-orientált például a
Java és a C
#. A C++-ban
használt osztályok a C-ben használt struktúrákból
 fejlődtek ki. Összesített
adattípust jelentenek, azaz különböző típusú adatokra és függvényekre lehet
egyetlen változóval hivatkozni, amit objektumoknak hívunk.





Példa:


#include


using namespace std;





struct Time


{


     int hour;   //0-23


     int minute; //0-59


     int second; //0-59


     void printShort();


     void printLong();


};





void Time::printShort() //13:30


{


     cout
"0"
: "")


          ":"


          "0" : "")


}





void Time::printLong()  //1:30:10 PM


{


     cout


          ":"


          "0" : "")


          ":"


          "0" : "")


          "
"


          "AM" : "PM");


}





int main()


{


     Time
timeObject,           // Time típusú objektum


          *timePtr,             // Time típusú mutató


          &timeRef = timeObject;// Time típusú referencia


            


     timeObject.hour
= 6;


               


     cout
"timeObject.hour = "



     cout
"timeRef.hour = "



    


     timePtr
= &timeObject;


     cout
"timePtr->hour = "

hour


    


     Time
Lunch;


     Lunch.hour
= 13;


     Lunch.minute
= 30;


     Lunch.second
= 10;


    


     cout
"Ebéd idő: "
;


     Lunch.printShort();


     cout
" azaz "
;


     Lunch.printLong();


    


     return 0;


}




A fenti programban egy Time nevű struktúra van definiálva, mely 3
változóval és 2 függvénnyel rendelkezik. A függvényeket lehetne a struktúrán
belül is definiálni, azonban szebb ha külön, a struktúrán kívül definiáljuk.
Mivel több struktúrának is lehet azonos nevű függvénye, a függvény neve elé
dupla kettősponttal oda kell írni a struktúra nevét is ahová tartozik.


A program elején három darab Time típus
van deklarálva: egy objektum, egy mutató és egy referencia. A struktúra
definiálása önmagában nem foglal semmi memóriát, ha nem használjuk akkor
szabadon marad a neki szánt tárhely. Amikor azonban egy Time típusú objektumot
deklarálunk, akkor lefoglalódnak a struktúrában deklarált változók helyei. A
struktúra tagjai a pont (.) és a nyíl (->) operátorokkal érhetőek el. A
pontot az objektumon vagy az objektum referenciáján keresztül való elérésénél
használjuk, míg a nyilat akkor, ha mutató segítségével hivatkozunk az
objektumra. A program kimenete a következő:





timeObject.hour
= 6


timeRef.hour = 6


timePtr->hour
= 6





Ebéd idő: 13:30
azaz 1:30:10 PM







A struktúrák a lehetőségek szempontjából korlátozottabbak
az osztályoknál, például nem lehet privát változókat deklarálni, melyeket csak
a tagfüggvények érhetnének el, mert alapból minden publikus, azaz kívülről
hozzáférhető. A programírás felügyelete pedig sokkal korlátlanabb a
struktúráknál, például megengedi, hogy inicializálatlanul hagyjuk a változókat
vagy hogy ne ellenőrizzük le annak helyességét (pl. egy interfészen keresztül). Az
osztályok esetén az ilyen hibákra már a fordításnál fény derül és ezzel
csökken a hibás programok írásának esélye. A gyakorlott programozók a
struktúrákkal is meg tudják oldani mindazt amit az osztályokkal lehet, ám sokkal
nagyobb erőfeszítést és figyelmet igényel.









4. Osztályok


     
Az osztályok implementálása nagyon hasonló a struktúrákéhoz. Lássuk az
előző programot osztállyal:





#include


using namespace std;





class Time


{


     public:               // bárhol elérhető


           Time();         //
konstruktor


           void printShort();


           void printLong ();


           void setTime(int, int, int);


     private:              // csak a tagfüggvények látják


           int hour;


           int minute;


           int second;


          


};





Time::Time()


{


     hour
= minute = second = 0; //inicializálás


}





void Time::printShort()


{


     cout
"0"
: "")


          ":"


          "0" : "")


}





void Time::printLong()


{


     cout


          ":"


          "0" : "")


          ":"


          "0" : "")


          "
"


          "AM" : "PM");


}





void Time::setTime(int
h, int m, int
s)


{


     hour
= (h >= 0 && h


     minute
= (m >= 0 && m


     second
= (s >= 0 && s


}





int main()


{           


     Time
t;    // a tagváltozók lenullázódnak a konstruktorban


    


     cout
"\nRövid változat: "
;


     t.printShort();


     cout
"\nHosszú változat: "
;


     t.printLong();


    


     t.setTime(13,27,6);


     cout
"\nRövid változat a setTime után:
"
;


     t.printShort();


     cout
"\nHosszú változat a setTime után:
"
;


     t.printLong();


    


     return 0;


}





A struktúráktól eltérően az osztályok
rendelkeznek
private, public és protected specifikációkkal. Ezek a tagokhoz
való hozzáférést határozzák meg. A privát tagokhoz csak a tagfüggvények férnek
hozzá (a főprogramban érhetőek el), a
publikushoz mindenki hozzáfér aki az objektumot is eléri, a protected tagokat pedig csak az örökös osztályok érhetik el. A tagfüggvényeket közvetlenül a
deklarálásnál is lehet definiálni, de szebb, ha csak a prototípust (deklarálást) írjuk az
osztályba, a definiálást pedig azon kívül, akár a struktúrák esetében. A tagfüggvények
összessége az osztály interfészét képezi, hiszen csak azokon keresztül érhetőek
el és módosíthatók a privát tagváltozók. Publikus tagváltozókat ritkán
használunk. A tagfüggvények listájába tartozik az osztály nevével azonos nevű
függvény, a konstruktor. Ez minden alkalommal automatikusan meghívódik
valahányszor létrehozunk egy objektumot, soha nem térít vissza semmit, ezért
ebbe a függvénybe a tagváltozók inicializálását szokás beírni.


A fenti program a következőt írja ki:





Rövid változat:
00:00


Hosszú változat:
12:00:00 AM


Rövid változat a setTime után: 13:27


Hosszú változat a setTime után: 1:27:06 PM





Pluszban van a setTime interfész tagfüggvény, ami a privát tagokhoz ad
hozzáférést és közben ellenőrzi, hogy a megadott értékek a megfelelő
tartományban vannak-e. A tagfüggvények olyan módon is megírhatók, hogy azok
közvetlen hozzáférést adjanak a privát változókhoz, ez viszont helytelen taktika,
ugyanis kiiktatja a változók ellenőrzését. Tegyük be az
int& badSetHour(int); függvényt a publikus tagfüggvények. Ez egy referenciát fog visszatéríteni,
a
hour változó referenciáját:





int& Time::badSetHour(int
h)


{


     int& ora = hour; // az "ora" a hour tagváltozó referenciája


     ora =
(h >= 0 && h
// ellenőrzés


     return ora;


}





A hour
tagváltozó kiirásához a következő publikus tagfüggvény használható:





int Time::getHour(){ return hour; }





Ezek segítségével a main()függvény végén közvetlenül lehet módosítani a hour tagváltozót akár hibás értékkel is:





int& hourRef = t.badSetHour(20); // itt még van belső ellenőrzés


hourRef = 87; //a
hour tagváltozó módosítása - ellenőrzés nélkül


cout "\nA módosított óra: " t.getHour();





A program kimenete:





Rövid változat:
00:00


Hosszú változat:
12:00:00 AM


Rövid változat a setTime után: 13:27


Hosszú változat a setTime után: 1:27:06 PM


A módosított óra: 87









5. Kódrendezés


     
A programozásban általában, főként az objektum-orientált programozásban
fontos, hogy a függvényeket és azok használatát külön felületre, más fájlokba helyezzük. Az osztályok esetén az osztály deklarálását, definícióját
és alkalmazását is elválasztják egymástól. Rendszerint az osztályokat header (fejléc) fájlokban deklarálják (.h), melyet aztán az include segítségével láthatóvá lehet
tenni a program számára. A fenti programot a következőképp lehet felbontani:





time.h


#ifndef TIME_H


#define TIME_H


class Time


{


     public:               // bárhol elérhető


           Time();         //
konstruktor


           void printShort();


           void printLong ();


           void setTime(int, int, int);


     private:              // csak a tagfüggvények látják


           int hour;


           int minute;


           int second;


          


};


#endif





time.cpp


#include


#include "time.h"


using std::cout;





Time::Time()


{


     hour
= minute = second = 0; //inicializálás


}





void Time::printShort()


{


     cout
"0"
: "")


          ":"


          "0" : "")


}





void Time::printLong()


{


     cout


          ":"


          "0" : "")


          ":"


          "0" : "")


          "
"


          "AM" : "PM");





void Time::setTime(int
h, int m, int
s)


{


     hour
= (h >= 0 && h


     minute
= (


This post first appeared on Altair Gate - News, please read the originial post: here

Share the post

Absztrakció

×

Subscribe to Altair Gate - News

Get updates delivered right to your inbox!

Thank you for your subscription

×