Objektum-orientált programozás



Hasonló dokumentumok
Osztályok. 4. gyakorlat

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

C++ programozási nyelv

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?

Objektumelvű programozás

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

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

Kivételkezelés, beágyazott osztályok. Nyolcadik 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

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

és az instanceof operátor

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

Bevezetés, a C++ osztályok. Pere László

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

Java és web programozás

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

Java és web programozás

Globális operátor overloading

OOP #14 (referencia-elv)

Objektumorientált programozás C# nyelven

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

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

Programozás II gyakorlat. 8. Operátor túlterhelés

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

C++ programozási nyelv Konstruktorok-destruktorok

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

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

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

Programozási nyelvek Java

Pénzügyi algoritmusok

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

Osztály és objektum fogalma

Programozási nyelvek Java

Java és web programozás

Programozás II. 4. Dr. Iványi Péter

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

1. Alapok. Programozás II

3. Osztályok II. Programozás II

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

1. Bevezetés A C++ nem objektumorientált újdonságai 3

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

Felhasználó által definiált adattípus

Objektumok inicializálása

JAVA PROGRAMOZÁS 2.ELŐADÁS

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

Programozási alapismeretek 4.

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

Programozás C++ -ban

Programozás II gyakorlat. 6. Polimorfizmus

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

Már megismert fogalmak áttekintése

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

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

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

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

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

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

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

Programozás módszertan

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.

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

Objektumorientált programozás C# nyelven

Java IX. telkezelés a Java-ban

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

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

Elemi Alkalmazások Fejlesztése II.

C programozási nyelv Pointerek, tömbök, pointer aritmetika

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

Programozás I. Első ZH segédlet

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

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

Java IX. telkezelés a Java-ban

OOP: Java 4.Gy: Java osztályok

OOP. Alapelvek Elek Tibor

Java Programozás 1. Gy: Java alapok. Ismétlés ++

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

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

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Smalltalk 3. Osztályok létrehozása. Készítette: Szabó Éva

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

Bevezetés a Python programozási nyelvbe

Szoftvertechnológia alapjai Java előadások

Objektumorientált szoftverfejlesztés alapjai

Kivételkezelés a C++ nyelvben Bevezetés

Objektumorientált programozás C# nyelven

Informatika terméktervezőknek

Szövegek C++ -ban, a string osztály

Programozás C++ -ban 2007/7

Programozás C++ -ban

Programozás C++ -ban

Apple Swift kurzus 3. gyakorlat

A C programozási nyelv III. Pointerek és tömbök.

GENERIKUS PROGRAMOZÁS Osztálysablonok, Általános felépítésű függvények, Függvénynevek túlterhelése és. Függvénysablonok

Programozás alapjai II. (4. ea) C++

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

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

Öröklés és Polimorfizmus

A C programozási nyelv III. Pointerek és tömbök.

Pénzügyi algoritmusok

Programozási nyelvek Java

Átírás:

Objektum-orientált programozás A programozás történetének során folyamatosan alakultak ki szabályok, amelyek célja a programkód átláthatósága, hibalehetőségek kizárása, alkalmazások közös fejlesztésének megkönnyítése és a már megírt kódrészletek újra felhasználása. Ilyen meggondolásból először strukturálttá tették a programkódot: az alaputasításokat kizárólag szekvenciálisan sorolhatjuk (lineárisan egymásután), elágazásokba (if, switch) és ismétlésekbe foglalhatjuk. Azelőtt lehetséges volt ugrálni a programsorok között. A fejlődés másik lépése az alfeladatokra való lebontás, alprogramok, modulok használata. Az alprogramokra bontott programot, már többen tudják fejleszteni és könnyebben javítható, hiszen a hiba egyszerűbben lokalizálható. irányzat. Az objektum-orientáltság egy újabb szint ebben a fejlődésben, ez az uralkodó programozási Az objektum-orientált programozás lehetővé teszi az adatok és a hozzá tartozó műveletek összezárását. Az objektum tervezője és fejlesztője kontrollálhatja az adatokhoz való hozzáférést. Az objektumok megértését elősegítheti a már használt C++ objektumok működésének elemzése. Ilyen objektumok (osztályok) a string, a queue és a stack. Az objektum-orientáltság string s; //a string az osztály, az s az objektum osztályok (class) írását jelenti. s="almafa"; //a string osztályban fölül van írva (értelmezve van) az Objektumnak az osztály egy példányát nevezzük. Pl: a string osztályt használhatjuk, ha karakterláncot szeretnénk tárolni. értékadás operátor, ezért használhatjuk az s esetén cout<<s; //a string osztályban fölül van írva a << operátor is for (int i=0;i<s.length();i++) s[i]=s[i]+1; //a string osztályban fölül van írva a [] operátor is, ezért indexelhetjük cout<<s; http://www.cplusplus.com/reference/string/string/ Az objektumokkal kapcsolatos fogalmakat a tört adatszerkezet (osztály) fokozatos felépítésével vegyük sorra. A megírt tört osztályt a stringhez hasonlóan, bármilyen törttel kapcsolatos feladat megoldása során használhatjuk. 1

A tört osztály 1. Adattagok - az osztályoknak (hasonlóan a struktúrához) adattagjaik vannak, amelyek lehetnek kifele látható (módosítható, lekérdezhető) vagy éppen láthatatlanok. Azért, hogy megvalósuljon az adatok védettsége nem tanácsos láthatóvá tenni őket. A tagokhoz csatolhatjuk a következő kulcsszavakat: a private (rejtett) ez az alapértelmezett érték. Az adattagot csak a metódusok és a friend alprogramok módosíthatják. a public (nyilvános) ez nem javasolt, mert bárki módosíthatja az értéküket. a protected (védett) hasonló a private-hoz, de az öröklődés során előállított leszármazott osztályokban is módosíthatóak. //ugyanúgy lehetne használni, mint a struct mezőit, ha nem lenne private, így nem matathatunk hozzájuk //előjel nélküli egész szám elég a számlálónak az előjel ; 2. Metódusok (setter, getter) alprogramok, amelyek az adattagokra vonatkoznak műveletek, amelyeket velük elvégezhetünk. Gyakori metódus típusok az adattagok értékeit lekérő és módosító (setter, getter) metódusok. Lehetővé teszik az ellenőrzött hozzáférést az adattagokhoz. //ezek nyilvános metódusok //a Get-esek visszatérítik egy-egy mező értékét int GetSzamlalo() { return szamlalo; unsigned int GetNevezo() { return nevezo; //a Set-eseknél ellenőrizhetjük, hogy a nevező ne legyen 0 void SetSzamlalo(int sz) { szamlalo=sz; void SetNevezo(unsigned int n) { if (n!=0) nevezo=n; ; 2

tort t; //a t egy tort objektum t.setnevezo(5); //a nevező és a számláló kissé bonyolult beállítása t.setszamlalo(4); cout<<t.getszamlalo()<<"/"<<t.getnevezo(); //a kiírás 3. Metódusok (konstruktorok) speciális metódus(ok), amelyek automatikusan meghívódnak az objektumok létrehozásakor: nevük az osztály nevével kell azonos legyen több is lehet, amennyiben más-más paraméterezéssel rendelkeznek visszatérített értéket nem kell megadni void-ot sem Ha a tort-höz adunk konstruktort, a Set-es alprogramokat esetleg módosításra maradhatna //konstruktor mivel a paramétereknek kezdőértéket adtam meghívható több módon is ha nincs változó a paraméter helyén, az alapértelmezett értéket adja át tort(int sz=0, unsigned int n=1) { szamlalo=sz; if (n!=0) nevezo=n; else nevezo=1; int GetSzamlalo() {return szamlalo; unsigned int GetNevezo(){return nevezo; ; int main(){ tort t, t1(5), t2(5, 4); //a t esetén nincs paraméter, ezért 0/1 lesz cout<<t.getszamlalo()<<"/"<<t.getnevezo()<<endl; //a t1 esetén csak az első paraméter kap más értéket, a második marad 1: 5/1 cout<<t1.getszamlalo()<<"/"<<t1.getnevezo()<<endl; //a t2-re kiírt érték: 5/4 cout<<t2.getszamlalo()<<"/"<<t2.getnevezo(); 3

4. Metódusok (az osztályon kívül) a gyakorlatban nem az osztályon belül szoktuk kifejteni a metódusok kódját. Az osztályon kívüli alprogramokat normális alprogramként kezeli a környezet, az inline függvényeket behelyettesíti a kódba, nem javasolt túl sok kódot így hagyni. Az alprogramok használatának épp az lenne az egyik lényege, hogy ne ismétlődjenek a kódok. tort(int sz=0, unsigned int n=1); //ha csak a kiírásra használnánk a get-es metódusokat, akár egy kiír-t is írhatunk. void Kiir(); ; //metódusok kifejtése az osztályon kívül tort::tort(int sz, unsigned int n) { szamlalo=sz; if (n!=0) nevezo=n; else nevezo=1; void tort::kiir(){ cout<<szamlalo<<" / "<<nevezo; ; tort t, t1(5), t2(5, 4); //az előző kiírást helyettesíthetjük a kiír metódussal t.kiir(); cout<<endl; t1.kiir(); cout<<endl; t2.kiir(); cout<<endl; 5. Metódusok (private) nem minden metódus nyilvános. Például, ha egyszerűsíteni szeretném időnként a törtet, ezt nem szükséges az osztályom felhasználójának is megengedjem. Egyszerűsíthetek a tört létrehozásakor, illetve ha valamilyen műveletet végzek vele. 4

tort(int sz=0, unsigned int n=1); void Kiir(); //csak az osztályon belül használható metódus void Egyszerusit(); ; tort::tort(int sz, unsigned int n) { szamlalo=sz; if (n!=0) nevezo=n; else nevezo=1; Egyszerusit(); //egyszerűsíthetem létrehozáskor void tort::kiir(){ cout<<szamlalo<<" / "<<nevezo; ; void tort::egyszerusit() { int a, b, r; a=szamlalo; b=nevezo; while (b){ r=a%b; a=b; b=r; szamlalo/=a; nevezo/=a; tort t2(5, 40); t2.kiir();cout<<endl; 6. Metódusok (túlterhelés) - ugyanolyan névvel több metódust is írhatunk. A feladatuk azonos, csak más kell legyen a paraméterezés. tort(int sz=0, unsigned int n=1); //a Kiir alprogram két változata következik, az újabb egy karakterláncot is kap, amit szintén kiír. void Kiir(); void Kiir(string sz); ; 5

tort::tort(int sz, unsigned int n) { szamlalo=sz; if (n!=0) nevezo=n; else nevezo=1; void tort::kiir(){ cout<<szamlalo<<" / "<<nevezo; ; void tort::kiir(string sz){ cout<<sz<<" "<<szamlalo<<" / "<<nevezo; ; tort t, t1(5, 40); t.kiir("elso tort");cout<<endl; t1.kiir();cout<<endl; 7. Metódusok ( kettős operátor túlterhelés) - a törtekhez értelmezhetjük a klasszikus C++ operátorok bármelyikét, azaz megadhatjuk, hogy mit értünk az alatt, hogy tört + tört vagy éppen tört * tört. Az értékadást az ilyen típusú objektumokra megy automatikusan a fenti alprogramok esetén ki lehet próbálni. Dinamikusan tárolt elemek esetén lehet gond és szükséges az értékadás felülírása. int main(){ tort t, t1(5, 40); t=t1; //a t tort 0/1, a t1 5/40 az értékadás következtében a t is 5/40 kell legyen t1.setszamlalo(11); //hogy leteszteljük, hogy a címét erőltette a t1 a t-re, vagy a mezők értékei lettek átmásolva lecseréltem a t1 számlálóját. Külön változnak, tehát nem közös a címük, a művelet sikerült. t.kiir("elso tort");cout<<endl; t1.kiir();cout<<endl; Az összeadás viszont már nem működik, tehát ha használni akarjuk, meg kell írni. Többféleképpen megoldható ez is. Kiegészíthető egyszerűsítéssel, a rend kedvéért és természetesen egyéb műveleteket is érdemes megírni. A példák tehát: 6

tort(int sz=0, unsigned int n=1); //ha egy tört után teszünk + jelet ez a metódus hívódik meg paraméter lesz, amit hozzá akarunk adni ez a t. Eredményként ennek a két törtnek az összege kerül visszatérítésre. tort operator+(tort& t); void Kiir(); ; tort tort::operator+(tort& t){ //a paraméterre hivatkozást adunk át. Így az eredeti objektummal dolgozunk, nem egy másolatával. Működik referencia nélkül is. tort eredm; //az eredm egy ideiglenes objektum, amely mezőinek értéke az értékadás révén az eredmény törtbe másolódnak. eredm.szamlalo=t.nevezo*szamlalo+t.szamlalo*nevezo; eredm.nevezo=nevezo*t.nevezo; return eredm; tort::tort(int sz, unsigned int n) { szamlalo=sz; if (n!=0) nevezo=n; else nevezo=1; void tort::kiir(){ cout<<szamlalo<<"/"<<nevezo; ; tort t, t2(1,2), t1(3, 2); t=t1+t2; t.kiir();cout<<" = ";t1.kiir();cout<<" + ";t2.kiir(); Igazán szép az lenne, ha a fejléc így nézne ki: const tort operator+(const tort& t) const 7

A const a konstansra értékét nem változtató adatra utal. Az eredmény const-ja miatt a t1+t2=t formájú utasításra hibát ad a környezet, mert az eredményként létrehozott ideiglenes törtet nem engedi változtatni, ezért nem is szerepelhet értékadás bal oldalán. A paraméter const-ja biztosítja, hogy bár a törtet, amit hozzáadunk az aktuális objektumhoz hivatkozással adtuk át, nem fogjuk az alprogramban véletlenül sem megváltoztatni. A harmadik const az aktuális objektumra vonatkozik, amelyet szintén nem indokolt változtatni. 8. Metódusok (friend függvény) - a kiírás alprogram helyettesíthető a << operátorral, nem is beszélve, hogy elegánsabb is. A << operátor végül nem a törtre, hanem valamilyen stream objektumra, ezért hiába akarjuk törtre fölülírni. Viszont használhatunk friend függvényt. Ezeket az alprogramokat az objektumon belül értelmezzük, de nem alkalmazhatjuk rájuk a private, protected kulcsszavakat. Az osztály barát alprogramja hozzáférhet az adott osztály egyébként rejtett mezőihez. tort(int sz=0, unsigned int n=1); //a friend kulcsszó jelzi a barátalprogramot //a törtet amit a << jel után teszünk paraméter lesz //azért kell visszatérített értéket adni, hogy láncolni lehessen a kiírást friend ostream & operator<<(ostream & ki, tort & t); ; //ide már nem kell friend ostream& operator<<(ostream &ki, tort& t){ //ki az ostreamre a hivatkozás képernyőre és állományra is mehet. ki<<t.szamlalo<<"/"<<t.nevezo; return ki; tort::tort(int sz, unsigned int n) { szamlalo=sz; if (n!=0) nevezo=n; else nevezo=1; 8

tort t(1,2); //mostmár nem kell a kiir cout<<t; 9. Metódusok (destruktor) Destruktor a konstruktor párja, akkor hívódik meg, amikor az objektum felszámolódik. A törthöz erre nincs szükség, a dinamikusan lefoglalt helyeket kell az objektum felszámolása esetén szabályosan felszabadítani. Ha megírnánk valahogy ilyen formája kellene legyen: ~tort(){cout<<"felszamolva!!!!"; 10. Hibakezelés (Hibák dobálása ) Programjaink futtatása közben felmerülhetnek olyan problémák, amelyek meghiúsítják az alprogram/program helyes végrehajtását, de amelyekre valamilyen formában reagálni kell. Az alprogram return-nal vagy paraméterként visszatéríthet számértékeket, amelyek alapján az alprogramot meghívó programozó eldöntheti mit kezd a hibával. Pl: a string osztálynak van egy find nevű metódusa, amely visszatéríti, hogy egy másik string hol van az alapstringen belül. Persze előfordulhat, hogy nincs meg benne. Ebben az esetben a visszatérített érték a string hosszának a lehető legnagyobb értéke. Ebből lehet kisütni, hogy nincs eredmény. string s="almafa"; if (s.find("bu")>s.length()) cout<<"nincs benne."; else cout<<"benne van."; Egy másik lehetőség a hiba feldobása, amelyet gyakran használnak objektum-orientált környezetben. Például a törtek esetén, ha 0 nevezőt adnak meg, lehet önkényesen helyettesíteni más értékkel, mint ahogy a fenti példákban vagy pedig jelezhetünk hibát. Ilyenkor az osztály leírásában nyilván meg kell adni, hogy miként reagál a konstruktor erre az esetre. Baj lehet akkor is, ha állományból olvasunk és nem létezik stb. Ez esetben nem igazán lehet a programot folytatni. tort(int sz=0, int n=1); friend ostream & operator<<(ostream & ki, tort & t); ; 9

ostream& operator<<(ostream &ki, tort& t){ ki<<t.szamlalo<<"/"<<t.nevezo; return ki; tort::tort(int sz, int n) { szamlalo=sz; if (n>0) nevezo=n; else if (n==0) throw(1); else throw(2); //átírtam a konstruktort, hogy ha 0 a nevező dobjon egy egyest, ha negatív (átírtam az n-et int-re) dob egy kettest. Lehet hibaüzenetet is. try{ tort t(1,-1); //ezek után, ha értelmezni akarok rossz törtet leáll a program, ennek elkerülésére jön a try catch... cout<<t; //a try-ba írom a problémás utasítást catch (const int val){ //a catch-be azt, hogy mit kezdjen, ha hiba lép fel if (val==1) cout<<"nincs tort! 0 a nevezo!"; if (val==2) cout<<"nem hozhattam letre a tortet! negativ nevezo"; vagy másképp a főprogram: int x, y; tort t; cin>>x>>y; try{ tort t1(x,y); t=t1; catch (const int val){ if (val==1) {tort t1(x,1); t=t1; if (val==2) {tort t1(x,-y); t=t1; 10

cout<<t; Gyakorlatok: 1. Írd meg kiegészítve a tort osztályt (alapműveletek, egyszerűsítés), majd írj egy programot, amely felhasználva az osztályt a következő opciókat kínál fel: a) művelet két törttel: összeadás kivonás szorzás osztás b) művelet egy törteket tartalmazó állományra: összeadás kiírás képernyőre 2. Írj egy nagyszámokat leíró osztályt. Nagyszám, ami már nem tárolható egy számként, hanem szükséges számjegyenként tárolni (Pl: tömbben). Írj programot, amely az osztályt felhasználva megvalósít egy nagyszámokkal foglalkozó számológépet. Bibliográfia: Emanuela Cerchez, Marinel Serban: Programarea în limbajul C/C++, vol. 4 11