subota, 20 aprila, 2024
Kako da...?

Uvod u objektno-orijentisano programiranje (2. deo)

Autor: Amar Tufo

U objavljenom 47. broju LiBRE! časopisa o slobodnom softveru imali ste priliku pročitati nešto detaljniji uvod u sam termin i srž objektno-orijentisanog programiranja gdje smo nastojali upoznati vas sa novim načinom razvoja softvera, njegovim prednostima, ali i manama. U ovom, drugom dijelu članka, o objektno-orjentisanom programiranju, upoznat ćemo Vas sa terminom klase i objekta, vidjet ćete na praktičnom primjeru kako se kreira jedna cijela klasa, a kako se kreira objekat, te njegovo pozivanje u samom programu. Spomenut ćemo termin mutatora i aksesora, te način njegove primjene na praktičnom primjeru. Treba napomenuti još jedanput kako ovaj članak nije uvod u programiranje niti je namjenjen početnicima s obzirom na to da je članak napisan pod pretpostavkom da ste već ranije radili u C++ programskom jeziku i da poznajete osnovne tipove podataka i petlje.

Šta je klasa, a šta objekat?

Jedna od novina koje objektno-orjentisano programiranje uvodi u razvoj softvera jesu klase i objekti. Prije nego pogledamo kako se zasebno pišu klase, treba da ukratko razjasnimo šta je to klasa a šta objekat.

Najjednostavniji odgovor na pitanje šta je klasa jeste da je to korisnički tip podataka. Dakle, klasa kao glavna karakteristika OOP-a omogućava programeru deklaraciju svog tipa podataka koju on kasnije može iskoristiti onoliko puta koliko mu to zatreba i tamo gdje mu zatreba. S druge strane, svaka se klasa sastoji od podataka članica klase koji mogu biti javnog (eng. public) ili privatnog (eng. private) metoda pristupa, te zaštićeni (eng. protected) metod pristupa. S obzirom na to da su svi podaci članice klase deklarisani kao privatni, njima se pristupa koristeći posebne funkcije po imenu mutatori i aksesori ili geter (eng. getter) i seter (eng. setter) funkcije. Da bismo bolje razumjeli ovaj tekst o klasama i objektima, pogledajmo primjer jedne jednostavne klase.

Gornji primjer prikazuje jednostavnu klasu Student sa podacima članovima klase height, age i name. U ovoj klasi, kao što se vidi, height i age su tip dabl dok je name tipa string. Svi podaci u ovom primjeru klase su privatnog tipa. Novina u ovoj klasi jeste kod posle linije void setHeight(double sheight), koji predstavlja funkcije mutatora i aksesora.

Zasebno pisanje klase i kreiranje objekta?

Prethodno u tekstu je pomenuto kako je klasa korisnički tip podataka te je također pomenuto od kojih se metoda pristupa sastoji jedna klasa. Međutim, nije pomenuto šta je objekat te kako se kreira objekat unutar klase. Najbolji primjer objekta je recimo auto, avion, pas, mačka. Svaki objekat ima svoje atribute, recimo auto ima težinu, boju, četiri točka, četvera vrata. To se u programiranju naziva objekat. Da bi se jedan auto napravio, prvo se izradi nacrt sa izgledom auta. Taj nacrt auta bi bio klasa, a sam auto bi bio objekat. U programiranju, objekat je sastavni dio klase i on se izrađuje u njoj. U našem slučaju, student je objekat koji ima svoje ime (string), godine (intidžer) te težinu (dabl). Sada mi možemo izraditi našu klasu koja bi izgledala ovako:

Ovako izgleda naša klasa po imenu Student kojoj smo dodjelili njene atribute. Već je napisano kako se svaka klasa sastoji od tri metoda pristupa članicama a to su javni, privatni i zaštićeni. No, u našem slučaju, mi koristimo samo prva dva navedena metoda. Kako se onda kreira objekat i šta je objekat uopšte? Najjednostavnije rečeno, objekat je instanca klase ili primerak klase.

U ovoj našoj klasi Student mi ćemo kreirati objekat po imenu student1. Dakle, ovo je objekat naše klase a koristit ćemo ga kako bismo dodjelili našem studentu ime (student1.setName = “Amar”).

Obzirom da su klase korisnički tipovi podataka, dobar programer će klasu uvijek zasebno pisati i definisati je kao svoj tip podataka. To je isto kada kreiramo zasebnu CSS datoteku naše veb stranice te ju kasnije samo uvežemo u našu HTML datoteku. Pogledajte oba slučaja:

Slika: Izgled gotove veb stranice sa CSS formatiranjem

Slika: HTML izvorni kod veb stranice

Slika: CSS datoteka veb stranice

Vjerovatno se pitate zašto smo ubacili HTML/CSS web stranicu kao primjer koja nema nikakve veze sa klasama i objektima. U pitanju je veoma dobra praksa da se CSS datoteka piše zasebno od HTML datoteke a da se kasnije samo poveže. Istu praksu primjenjujemo na klase i objekte.

Slika: Izgled klase Student

Slika: Deklarisanje tipova članica klase Student

Ukratko, na slici 4 se vidi kako naša klasa počinje sa #ifndef ,#define, čime se definiše korisnički tip podataka. U C++-u, klasa počinje malim početnim slovom class Student , dok naziv klase pišemo velikim početnim slovom. Jednom kada deklariramo sve članove naše klase kao na slici iznad, deklaraciju klase završavamo #endif. Time je naša klasa deklarisana. Međutim, na slici 5 koja prikazuje definiciju funkcija članica klase, imamo prikazanu upotrebu mutatora i aksesora. Ukoliko Vas kojim slučajem buni dio koda na slici 5 Student::setAge, radi se o operatoru za razrešenje dosega (::, eng. scope operator). Operator za razrešenje dosega čita deklarisane podatke iz moje klase kako bi se studentu dodjelile njegove godine ili ime. Ovako se pravilno kreira jedna klasa, a obavezno Vam preporučujemo da radite na isti način te izbjegavajte pisanje klase unutar main.cpp datoteke kako ne bi došlo do nepreglednosti u kodu, a prednost je i lakša modifikacija i otklanjanje nastalih grešaka. Posljednji dio našeg programa koji nam je ostao, jeste da se klasa poveže u main.cpp datoteku. Ono što treba dodatno naponetu dodati jeste i to što jednom kada se klasa kreira, ovisno o razvojnom okruženju koje koristite, valja imati na umu da je klasa heder datoteka, odnosno, student.h koja sadrži deklaracije prototipova funkcija te isto ime se dodjeljuje za datoteku student.cpp koja sadrži definicije prototipova funkcija.

Još jedna važna stvar koju koristi naša klasa jesu mutatori i aksesori. Dakle, šta su uopšte mutatori i aksesori? Ukratko, mutator je posebna funkcija klase koja postavlja vrijednost na varijablu privatnog člana klase dok aksesor vraća vrijednost člana klase. Gornja klasa Student ima deklarisane funkcije klase koristeći se mutatorima i aksesorima a u nastavku ćemo pogledati kako se definišu funkcije klase. Najjednostavnije rečeno, mutatori i aksesori su u stvari funkcije kojima se varijablama dodjeljuju njihove vrijednosti. Mi u ovom našem programu imamo studenta kome želimo da dodelimo ime i da se njegovo ime vrati na izlaz pošto se program kompajlira. Ime studenta je tipa string pa kodom to pišemo ovako:

string name;

Sada moramo upotrebom funkcije mutatora (seter) postaviti ime našeg studenta, a to radimo upotrebom operatora za razrešenje dosega :: ovako:

void Student::setName (std::string sname) { std::string name = sname; }

std::string Student::getName(void) { return _name; }

Jedanput kada smo definisali prototipove funkcija, u glavnom dijelu koda treba samo da dodjelimo vrijednosti našoj varijabli, u ovom slučaju da damo ime našem studentu. Prvo se kreira objekat koji izgleda ovako:

Student student; //ovo je objekat

Sada dodjelimo ime našem studentu na ovaj način.

student.setName(“Amar”);

cout «”\n Name: “ «student.getName()«endl;

Sada ponovo možemo obratiti pažnju na naš cijeli program u koji je povezana naša klasa a koji izgleda ovako:

Slika: Izgled cijelog programa main.cpp

Drugi dio članka o objektno–orjentisanom programiranju bio je nešto detaljniji s obzirom na to da je kreiran praktični program po imenu Student v1.0 u kojem je prikazana izrada klase i objekta, mutatora i aksesora. U trećem dijelu članka prikazat ćemo način kompajliranja ovog C++ programa koristeći Terminal i GNU/G++ kompajler.

Prethodni deo