Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Objektum-orientált szoftverfejlesztés

Hasonló előadás


Az előadások a következő témára: "Objektum-orientált szoftverfejlesztés"— Előadás másolata:

1 Objektum-orientált szoftverfejlesztés
OO módszertan alkalmazásával a kifejlesztendő rendszert együttműködő objektumokkal modellezzük, a tervezés és az implementáció során pedig ezen objektumokat „szimuláló” programegységeket alakítunk ki.

2 Objektum-orientált módszertanok
Rumbaugh Booch Coad UML (Unified Modeling Language)

3 Az objektum külvilág felé mutatott viselkedésével,
Az objektum egy rendszer egyedileg azonosítható szereplője, amelyet a külvilág felé mutatott viselkedésével, belső struktúrájával és állapotával jellemezhetünk.

4 Az objektum-orientáltság fogalma

5 Az objektum felelőssége
Az objektumtól elvárjuk, hogy maradéktalanul eljátssza a rárótt szerepet, azaz rendelkezzen minden olyan ismerettel és képességgel, amire ehhez szükség van .

6 Az objektum viselkedése
Az objektum viselkedése az általa végrehajtott tevékenységsorozatban nyilvánul meg. Viselkedés jellege szerint az objektum: Aktív (folyamatosan működik, más objektumokat működésre bír) Passzív ( mindaddig nem tesz semmit, amíg valamilyen környezeti hatás nem éri)

7 Üzenetek Az objektumok üzeneteken keresztül hatnak egymásra.
Az üzenetek szerepe: Az objektumok közötti adatcsere Objektumok működésének vezérlése

8 Az üzenet Komponensei:
Az üzenet neve Az üzenet paraméterei (üzenet tartalma) Egy adott nevű üzenet a működés során többször elküldhető (üzenet konkrét példányai) Egy objektum több különböző nevű üzenet fogadására képes. (Az üzenet neve vezérlő jellegű)

9 Az üzenet paraméterei Az üzenet neve meghatározza, hogy milyen paraméterek kapcsolhatók az üzenethez Azonos nevű, különböző paraméterekkel kapott üzenetek az objektum azonos reakcióját indítják el, amely aztán a paraméterek értelmezését követően különbözőképpen folytatódhat. A paraméter objektum is lehet.

10 Események Eseménynek az azonosítható, pillanatszerű történést nevezzük
Eseményeket az objektumok hozzák létre. Üzenet és esemény hasonlósága (posta hasonlat: levél, csomag, pénzesutalvány – levél megérkezése)

11 Metódusok Az üzenet hatására az objektum valamilyen cselekvést hajt végre - az üzenet neve által meghatározott metódus végrehajtódik. Ugyanazon objektum azonos tartalmú üzenetekre különbözőképpen reagálhat (attól függően, hogy korábban milyen hatások érték.

12 Állapot Az objektum állapotát attribútumai tárolják.
Az attribútumok értékei az objektum élete során változhatnak (változókkal definiálhatjuk a szoftverben)

13 Polimorfizmus Ha egy objektum úgy küldhet üzenetet egy másik objektumnak, hogy nem kell figyelemmel lennie arra, hogy ki az üzenet vevője, akkor polimorfizmusról beszélünk

14 Osztályok és példányok
A megegyező viselkedésű és struktúrájú objektumok egy közös minta alapján készülnek. Ezt osztálynak (esetleg objektumosztálynak) nevezzük. Az objektum az osztály egy példánya.

15 Módszertanok OMT- módszertan Szögletes sarkú doboz – osztály
Lekerekített sarkú doboz - objektum (Kutya) Blöki Kutya

16 Osztálydiagram és objektumdiagram egy eleme
(Kutya) Blöki Korcs 2 Kutya Név:text Fajta:text Kor:integer Gazdát_cserél beoltják

17 Az objektum és környezete közötti csatolás
Gyenge legyen a csatolás! Az objektum és környezete közötti csatolás akkor a leggyengébb, ha az objektum metódusain belül csak az alábbi elemekre történik hivatkozás A metódus paramétereire A metódust tartalmazó osztály attribútumaira A program globális változóira A metódusban definiált lokális változókra

18 Az objektumok típusai A típus egy objektum-halmaz viselkedését specifikálja. Definiálja az objektum által értelmezett üzeneteket és az operációk szemantikáját. Az osztály a típus által meghatározott viselkedést implementálja. Egy típus különféle struktúrájú osztályokkal is implementálható.

19 Objektum-változó Változó fogalma: olyan elem, amely alkalmas érték befogadására Objektum-változó: olyan szerkezet, amely alkalmas objektum tárolására. Objektum-változónak küldött üzenet: a változó által éppen tartalmazott objektumnak szóló üzenet.

20 A programozási nyelvek változói
Statikusan tipizáltak (PASCAL szigorúan típusos, C kevésbé szigorúan típusos) Dinamikusan tipizáltak ( a változónak nincs előre meghatározott típusa, futás közben tetszőleges értéket felvehet. Ezek az értékek tetszőleges típusúak lehetnek.

21 Műveletek változókkal
A változón végrehajtott műveleteket meghatározhatja maga a változó, vagy a változóban tárolt érték. A művelet és a változó kapcsolódását kötésnek (binding) nevezzük.

22 A kötések típusai Statikus kötés: a változó típusa határozza meg a műveleteket. Objektumváltozó esetén a metódusokat. Dinamikus kötés: a változó által hordozott érték határozza meg a műveleteket. (Objektumváltozó esetén a metódusokat.)

23 Objektum - orientált programozás C++ -ban
1

24 Objektum - orientált programozás
A programozás az ún. Imperatív nyelvekben (mint a C, a Pascal, a Fortran, a Basic és a C++) nem jelent mást, mint egy feladat megoldási menetének (algoritmusának) megfogalmazását a programozási nyelv nyelvtanának és szókincsének felhasználásával. 2

25 Objektum - orientált programozás
Objektum-orientált nyelvek C++ JAVA ADA Modula-2 LISP 3

26 A C++ nyelv A C++ nyelv alapelemei az osztályok.
Egy osztály nem más, mint a felhasználó által definiált új típus, amely a szükséges adatstruktúrákat és az adott struktúrájú adatokkal végezhető műveleteket definiálja. 4

27 Objektum - orientált programozás jellemzői 1.
Egységbezárás (Encapsulation) Adatokat és függvényeket egy egységként kezeljük és elzárjuk őket a külvilágtól. Ezeket az egységeket objektumoknak nevezzük. Az objektumok tárolási egységének típusa: class (osztály). 5

28 Objektum - orientált programozás jellemzői 2.
Öröklés (Inheritance) Meglévő osztályokból újabb osztályok hozhatók létre, amelyek öröklik a definiálásukhoz szükséges alaposztályok adatstruktúráit és függvényeit, ugyanakkor újabb tulajdonságokat is definiálhatnak, vagy régieket újraértelmezhetnek. Osztályhierarchia. 6

29 Objektum - orientált programozás jellemzői 3.
Többrétűség (Polymorfizm) Ez alatt azt értjük, hogy egy adott tevékenység (metódus) azonosítója közös lehet egy adott osztályhierarchián belül, ugyanakkor a hierarchia minden osztályában a tevékenységet végrehajtó függvény megvalósítása az adott osztályra nézve specifikus. Virtuális függvények. Operator overloading. 7

30 Az egységbezárás előnyei
Dátum kezelésének problémái Igények a dátum kezelésével kapcsolatban Rendelkezésre álló eszközök

31 Dátum tárolása struct date { int month ; int day ; int year ; };
Értékadás a struktúra adattagjainak struct date my_date ; my_date.month = 1; my_date.day = 23; my_date.year = 1985 ; 8

32 Dátum megjelenítése void display_date ( struct date *dt ) {
static char *name [ ] = {“zero” , “January” , February” , “March” , “April” , “May” , “June” ,“July” , August” , September” , “Oktober” ,“November” , “December” } ; printf (“%s %d %d”, name [ dt - > month], dt ->day , dt -> year) ; } 9

33 Problémák a technikával kapcsolatban
Nem garantálja, hogy a struktúra elemei érvényes dátumot tartalmazzanak. Pl. Február 31. Ha egyszer a date adattípust használtuk a programban, akkor nagyon nehéz megváltoztatni annak implementációját. Pl. a hónapot és napot egy egészként kezelni. Mindenütt meg kell változtatni a programot, ahol hivatkozás történik rá. 10

34 Megoldás Ezek a problémák az OOP-ben úgy kerülhetők el, hogy a date struktúrán belül kell használni egy olyan függvényt, amely a struktúra elemeihez tartozó értékek érvényességét ellenőrzik. Ezenkívül tartalmaznak olyan függvényeket, amelyek a struktúra adattagjainak értékét szolgáltatják. 11

35 A dátum osztály definíciója
#include <iostream.h> class Date { public: Date ( int mn, int dy, int yr) ; void display ( ) ; ~Date ( ) ; private: int month ; int day ; int year ; } ; 12

36 Néhány hasznos (segéd) függvény
inline int max ( int a , int b ) { if ( a > b ) return a ; return b ; } inline int min ( int a , int b ) { if ( a < b ) return a ; 13

37 Konstruktor (a dátum értékének megadása ellenőrzéssel)
Date::Date ( int mn , int dy , int yr ) { static int length [ ] = { 0,21,28,31,30,31,30,31,31,30,31,30,31 } ; month = max ( 1 , mn ) ; month = min ( month, 12 ) ; day = max ( 1 , dy ) ; day = min ( day, length [ month ] ) ; year = max ( 1, year ) ; } 14

38 Tagfüggvény (megjelenítés)
//void Date::display() { static char *name [ ] = {“zero” , “January” , February” , “March” , “April” , “May” , “June” ,“July” , August” . September” , “Oktober” ,“November” , “December” } ; cout << name [ month ] << ‘.’ << day << ‘.’ << year ; } 15

39 Destruktor //Destructor Date::~Date( ) { //do nothing } 16

40 Program, ami demonstrálja a Date class-t.
void main ( ) { Date myDate ( 3, 2, 1985 ); Date yourDate ( 23, 259, 1966 ) ; myDate.display ( ) ; cout << ‘\n’ ; yourDate.display ( ) ; } 17

41

42 Osztály fogalom Új fogalom: osztály (class).
Az osztály olyan általánosított struktúrának tekinthető, amely egységbe zárja az adatokat és a műveleteket - és alapértelmezésben minden tagja, függetlenül attól, hogy adatról vagy függvényről van szó - az osztályon kívülről elérhetetlen. 18

43 A Date osztály class Date { public: Date ( int mn, int dy, int yr) ;
int getMonth ( ) { return month ; } int getDay ( ) { return day ; } int getYear ( ) { return year ; } int setMonth ( int mn ); int setDay ( int dy ) ; int setYear ( int yr ) ; void display ( ) ; ~Date ( ) ; private: int month ; int day ; int year ; } ;

44 public és private kulcsszavak
Publikus (public) tagok - kívülről elérhető tagok. Privát (private) tagok - kívülről elérhetetlen tagok. Egy olyan osztály, amelynek egyetlen tagja sem elérhető, semmire sem használható. private és public kulcsszavakkal a hozzáférés szelektív engedélyezése és tiltása valósítható meg. Hatása addig tart, amíg meg nem változtatjuk újabb private vagy public kulcsszóval. 19

45 public és private kulcsszavak
Általában az adattagokat szoktuk private-tal a függvényeket public-cal definiálni. A struktúrában is használhatók ezek a kulcsszavak Struktúrában alapértelmezés a public hozzáférés a tagokhoz. 20

46 Tagfüggvények Ezeket szokás még metódusoknak illetve üzenetnek is nevezni. Eddig csupán a függvények deklarációját helyeztük el az osztály deklarációjának belsejében. A függvények törzsének a megadása során két megoldás közül választhatunk: - definiálhatjuk őket az osztályon belül (deklaráció és definíció nem válik el egymástól) - definiálhatjuk őket az osztályon kívül (deklaráció és definíció szétválik). 21

47 Megjegyzések a példával kapcsolatban
A tagfüggvényekben a privát adattagok közvetlenül elérhetők. (A C függvény hivatkozik a dt.month nevű struktúraváltozóra. A C++ tagfüggvény közvetlenül eléri a month változót. 22

48 Megjegyzések a példával kapcsolatban
Ha a tagfüggvényt osztályon kívül definiáltuk, akkor azt is egyértelműen jelezni kell, hogy melyik osztályhoz tartozik, hiszen egy Date nevű tagfüggvénye több osztálynak is lehet. Erre a célra szolgál az ún. scope operator (::), melynek segítségével a Date::display() formában a Date osztály display tagfüggvényét jelöljük ki. 23

49 Metódus osztályon kívüli definíciója
void Date::display() { static char *name [ ] = {“zero” , “January” , February” , “March” , “April” , “May” , “June” ,“July” , August” . September” , “Oktober” ,“November” , “December” } ; cout << name [ month ] << ‘.’ << day << ‘.’ << year ; }

50 Megjegyzések a példával kapcsolatban
Az osztályon belül definiált tagfüggvény automatikusan inline függvény lesz. (Áttekinthető osztálydefiníciókban úgyis csak tipikusan egysoros függvények engedhetők meg, amelyeket hatékonysági okokból makróként célszerű deklarálni. 24

51 Megjegyzések a példával kapcsolatban
Minden tagfüggvényben létezik egy nem látható paraméter, amelyre this elnevezéssel lehet hivatkozni. A this mindig az éppen aktuális objektumra mutató pointer. Így a saját adatmezők is elérhetők ezen keresztül, tehát az x helyett a függvényben this -> x -t is írhatnánk. 25

52 Az osztályok nyelvi megvalósítása
Az osztály működésének jobb megértése érdekében érdemes egy kicsit elgondolkodni azon, hogy hogyan valósítja meg azt a C++ fordító. C++ -ról C-re fordító programot kell írnunk (Tételezzük fel!) Vizsgáljuk meg, hogy a fogalmainkat hogyan lehet leképezni a C nyelvre! 26

53 Az osztályok nyelvi megvalósítása 1.
A C nyelvben az osztályhoz legközelebbi adattípus a struktúra. Az osztály adattagjait egy struktúrában helyezzük el. A függvénymezőket globálisként kell kezelnünk. A névütközések elkerülése végett a globális függvénynevekbe bele kell kódolni azon osztály nevét, amelyhez tartozik, sőt, ha ezen függvénynévhez különféle paraméterezésű függvények tartoznak akkor a paraméterek típusait is. Pl. display_Date ( ha paramétere lenne, pl. 3 db int, akkor display_Date_intintint. 27

54 Az osztályok nyelvi megvalósítása 2.
A különválasztás során, ha például 1000 db Date objektumunk van, akkor látszólag 1000 db display függvénynek kellene léteznie. Ha még hozzátesszük, hogy az objektumok dinamikusan keletkezhetnek és szűnhetnek meg a program futása során, akkor látható, hogy nem ez a járható út. A feladatot egyetlen display függvénnyel kell elvégezni, de hogy az tudja, hogy milyen adatokkal kell dolgoznia, meg kell kapnia annak az objektumnak a címét, amelynek az adattagjait kezeli. 28

55 Az osztályok nyelvi megvalósítása 3.
Ennek a legegyszerűbb megvalósítása az, hogy a függvény megkapja az adatstruktúra kezdőcímét első paraméterként. Minden tagfüggvény első nem látható paramétere az adattagokat összefogó struktúra címét tartalmazó mutató. Ez a mutató nem más, mint az objektum saját címe, azaz a this pointer. A this pointer alapján a lefordított program az összes objektum attribútumot indirekt módon éri el. 29

56 Fontos! Privát tagokat csak az osztály tagfüggvényei érik el (és a friend class) Példa: void main ( ) { int i ; Date myDate ( 3, 12, 1985 ) ; i = myDate.month ; // hiba myDate.day = 1 ; // hiba } 30

57 Fontos! myDate.display ( ) //myDate adattagjait jeleníti meg;
Csak tagfüggvényeken keresztül hivatkozhatunk az adattagokra. myDate.display ( ) //myDate adattagjait jeleníti meg; yourDate.display ( ) //yourDate adattagjait jeleníti meg; Egy tagfüggvény automatikusan használja a kurrens objektum adattagjait Egy tagfüggvényt pointeren keresztül is hívhatunk: Date myDate ( 3, 12, 1985 ); Date *datePtr = &myDate ; datePtr -> display (); 31

58 Tagfüggvények hívása referenciával
Date myDate ( 3, 12, 1985 ); Date &OtherDate = myDate ; OtherDate.display (); //myDate tartalmát jeleníti meg 32

59 Konstruktor A Date osztály alapján objektumokat (változókat) definiálhatunk, melyeket a szokásos módon értékadásban felhasználhatunk, illetve tagfüggvényeik segítségével üzeneteket küldhetünk nekik. A C++ osztályok rendelkezhetnek egy olyan speciális tagfüggvénnyel, amely akkor kerül meghívásra, amikor egy objektumot létrehozunk. Ezt a tagfüggvényt konstruktornak nevezzük. A konstruktor neve mindig megegyezik az osztály nevével. 33

60 Konstruktor A Date osztály konstruktora a Date() függvény!
Egy osztálynak több konstruktora is lehet. Ha egy osztálynak nincs konstruktora, akkor a fordító egy paraméter nélküli változatot automatikusan létrehoz. Ha viszont bármilyen bemenetű konstruktort megadunk, akkor automatikus konstruktor nem jön létre. Az argumentumot nem váró konstruktort alapértelmezés szerinti konstruktornak nevezzük. Az alapértelmezés szerinti konstruktort feltételező objektumdefiníció során a konstruktor üres () zárójeleit nem kell kiírnunk. 34

61 Fontos! Privát tagokat csak az osztály tagfüggvényei érik el (és a friend class) Példa: void main ( ) { int i ; Date myDate ( 3, 12, 1985 ) ; i = myDate.month ; // hiba myDate.day = 1 ; // hiba } 30

62 Fontos! myDate.display ( ) //myDate adattagjait jeleníti meg;
Csak tagfüggvényeken keresztül hivatkozhatunk az adattagokra. myDate.display ( ) //myDate adattagjait jeleníti meg; yourDate.display ( ) //yourDate adattagjait jeleníti meg; Egy tagfüggvény automatikusan használja a kurrens objektum adattagjait Egy tagfüggvényt pointeren keresztül is hívhatunk: Date myDate ( 3, 12, 1985 ); Date *datePtr = &myDate ; datePtr -> display (); 31

63 Tagfüggvények hívása referenciával
Date myDate ( 3, 12, 1985 ); Date &OtherDate = myDate ; OtherDate.display (); //myDate tartalmát jeleníti meg 32

64 Objektumdefiníció Date myDate( 3, 12, 1985) ; Date myDate( ) ;
Bármikor egy objektumot definiálunk, akkor a konstruktor végrehajtásra kerül. 35

65 Globális objektumok Globális objektumok a program betöltése alatt, azaz a main() meghívása előtt születnek meg, így konstruktoruk is a main() hívása előtt aktivizálódik. Ezekben az esetekben a konstruktor argumentuma csak konstans kifejezés lehet, és nem szabad olyan dolgokra támaszkodnunk, amelyet a main() inicializál. 36

66 Objektumok tömbje Date d [100];
Ebben az esetben nem tudunk argumentumokat átadni, ezért tömb csak olyan típusú objektumokból hozható létre, amelyek alapértelmezésű konstruktorokat tartalmaznak. 37

67 Objektumok definiálása
Az objektumokat definiálhatjuk dinamikusan is, azaz memóriafoglalással (allokáció), a new és a delete operátorok segítségével. Természetesen egy dinamikusan létrehozott objektum a new operátor alkalmazásakor születik meg és a delete operátor alkalmazásakor vagy a program végén szűnik meg, így a konstruktor és a destruktor függvények hívása is a new és a delete operátorhoz kapcsolódik. A new operátorral történő memóriafoglalásnál a kért objektum típusa után meg kell adni a konstruktor argumentumait is: Date *pd = new Date ( 3, 12, 1985 ) ; Date *pdt = new Date [100] ; 38

68 A delete operátor A delete operátor egy objektumra értelemszerűen használható (delete pd, de tömbök esetében a delete pdt hatására felszabadítás ugyan megtörténik, de csak az első objektumra hívja meg a destruktort. Ha feltétlenül mind a 100 elemre meg akarjuk hívni a destruktort, akkor így kell használni: delete [ ] pdt ; 39

69 Destruktor Ha egy objektum érvényességi tartománya megszűnik, akkor meghívásra kerül a destruktor függvény. Szerepe: egy objektum megszüntetése Igazán akkor lényeges, ha az objektumok dinamikus memóriát használnak. A destruktor neve megegyezik az osztály nevével, csak előtte ~ (tilde) jel legyen. A destruktornak nincs paramétere nem lehet visszatérési értéke nem átdefiniálható. 40

70 A konstruktor is overload-olható
class Date { public: Date ( ) ; //Konstruktor paraméterek nélkül Date ( int mn, int dy, int yr) ; int getMonth ( ) { return month ; } int getDay ( ) { return day ; } int getYear ( ) { return year ; } int setMonth ( int mn ); int setDay ( int dy ) ; int setYear ( int yr ) ; void display ( ) ; ~Date ( ) ; private: int month ; int day ; int year ; } ; Date::Date ( ) month = day = year = 1 ; //Inicializálja az adattagokat. }

71 Demo program a konstruktorok és destruktorok futásával kapcsolatban
#include <iostream.h> #include <string.h> class Demo //Demo osztály definíciója { public: Demo (const *nm ); ~Demo ( ) ; private: char name [ 20 ] ; } ;

72 // Demo konstruktora Demo::Demo ( const char *nm ) {
strncpy ( name, nm, 20 ) ; cout << “Constructor called for “ << name << ‘\n’ ; } //Demo destruktora Demo::~Demo ( ) cout << “Destructor called for “ << name << ‘\n’ ;

73 Egy függvény egy lokális és egy statikus lokális objektum definiálásával
void func ( ) { Demo localFuncObject (“localFuncObject”) ; static Demo staticObject (“staticObject”) ; cout << “Inside func\n” ; }

74 Egy globális objektum definiálása
Demo globalObject (“globalObject”) ; void main() { Demo localMainObject (“localMainObject”) ; cout <<”In main, before calling func\n” ; func ( ) ; cout <<”In main, after calling func\n” ; }

75 A program a következőket nyomtatja ki:
Constructor called for globalObject Constructor called for localMainObject In main, before calling func Constructor called for localFuncObject Constructor called for staticObject Inside func Destructor called for localFuncObject In main, after calling func Destructor called for localMainObject Destructor called for staticObject Destructor called for globalObject


Letölteni ppt "Objektum-orientált szoftverfejlesztés"

Hasonló előadás


Google Hirdetések