Professional Documents
Culture Documents
Klase i objekti
Klasa je osnovna jedinica programiranja u Javi. Klase obezbeđuju strukturu objekata, kao i
mehanizme za proizvodnju objekata, na osnovu datih definicija u klasi. Klase definišu
metode, skupove izvršivog koda, koje izračunavaju podatke i njima upravljaju unutar
objekta. One obezbeđuju ponašanje objekata klase.
Klasa sadrži:
polja (definišu stanje svakog objekta klase – struktura podataka, podaci)
metode (operacije, funkcije koje sadrže izvršni kod i definišu ponašanje objekta)
mehanizme za stvaranje objekata na osnovu definicije (konstruktori)
Ovakva kombinacija metoda, podataka i semantike pisanja koda se opisuje kao ugovor
između projektanata klase i programera koji je korsiti, pošto opisuje šta se dešava kada
određena pozvana metoda deluje na objekat. Ovaj ugovor definiše tip, tako da se
podrazumeva da će ga poštovati svi objekti koji predstavljaju primerke tog tipa.
Kada posmatramo objekat, pitanje kako je dedfinisano njegovom klasom, koja definiše
implementaciju metoda koje je objekat sposoban da izvrši. Svaki objekat je primerak klase.
Kada pozvana metoda deluje na objekat, ispituje se klasa, u potrazi za kodom metode koji
je potrebno da se izvrši.
Jednostavna klasa
Hajde da predstavimo našu prvu klasu u Javi. Kao primer izabraćemo neku manifestaciju u
kojoj učestvuju studenti sa mentorima. Naime, svaki student ima svog kolegu kao mentora
u određenom projektu, koji je takođe student. Studenti na manifestaciji nastupaju po redu,
koji je određen brojem indeksa. Nije obavezno da svaki student ima mentora. Pitanje je
kako predstaviti objekat tipa “Student”?
class Student {
int index;
String ime;
Student mentor;
1/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Kao što se može primetiti, klasa “Student” deklasrisana je ključnom rečju class, imenom
klase Student i navođenjem članova klase unutar vitičastih zagrada. Skup svih članova
klase unutar tih zagrada naziva se telo klase. Ovakva deklaracija klase stvara ime tipa,
tako da je sada moguće deklarisati reference na objekte tog tipa:
Ova deklaracija govori da je mentor promenljiva koja sadrži referencu na objekat tipa
“Student”. Deklaracija NE pravi objekat, već samo deklariše referencu koja sme da se
odnosi na objekte tipa “Student”. Tokom svog postojanja, ova referenca se može odnositi
na bilo koji objekat tipa “Student”, ali ne i na druge tipove objekata. Svi ovi objekti moraju
se eksplicitno napraviti, radi korišćenja u programu.
Pored polja, metoda i konstruktora, klasa može sadržati i tzv. ugnježdene tipove, a to su
interne klase i interfejsi ove klase. Deklaraciji klase mogu prethoditi modifikatori klasa,
koji joj daju određena svojstva:
Deklaraciji klase može prethoditi više različitih modifikatora. Ne postoje pravila po pitanju
njihovog redosleda, mada se preporučuje dosledan redosled koji unapređuje čitljivost koda.
Polja
Klasne promenljive se zovu polja. Primeri polja, u prethodno datom primeru u klasi
“Student”, su: index, ime, i mentor. Deklaracija polja sastoji se iz imena tipa iza koga
dolazi ime polja i, po potrebi, inicijalizirajuća klauzula (klauzula = odredba, uslov koji
ograničava). Ova klauzula daje polju njegovu inicijalnu vrednost. Kada ona nije prisutna u
deklaraciji, polje dobija default (podrazumevanu) vrednost.
Pogledajmo ponovo primer klase “Student”. Svaki objekat ove klase ima svoje specifične
primerke polja klase (int vrednost koja označava broj indexa i time jedinstveno
identifikuje studenta, String vrednost koja označava ime studenta, kao i vrednost tipa
Student, koja referencira njegovog mentora itd.). Ovo znači da svaki objekat ima svoje
jedinstveno stanje.
2/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Polja koja odražavaju stanje koje je jedinstveno nazivaju se promenljive primerka. Kada
bi vrednost polja u nekom objektu bilo promenjeno, to nece uticati ni na jedno drugo polje
ostalih objekata.
Objašnjenja nekih modifikatora: Kada je polje deklarisano kao volatile, to znači da mu više niti može
pristupati simultano. Za bolju koordinaciju među pristupima polju od strane konkurentnih niti potrebno je
koristiti modifikator synchronized. Naravno, učenje niti izlazi iz osnovnih domena ovog kursa, pa ovo
neće biti dalje razrađivano kao pojam. Modifikator transient ima veze sa tzv. serijalizacijom klasa
(objekata), gde se ovako deklarisana polja ne čuvaju niti čitaju, o čemu će biti reči kasnije tokom kursa.
Ponekad je potreno da postoji samo jedan primerak polja koji dele svi objekti klase. Ova
polja se deklarišu kao static. Zovu se statička polja ili promenljive klase. Tada postoji
samo jedno polje, bez obzira na broj primeraka klase.
U primeru studenta, brojStudenata je statičko polje, koje sadrći broj studenata koji
učestvuje u manifestaciji. Polje je inicijalizovano nulom nakon učitavanja klase. Svaki
novonastali objekat tipa “Student” imaće ovaj identifikator, a njegovu vrednost
povećavaćemo svakim novim objektom. Logično je da će postojati samo jedan primerak
ovog polja i da će važiti za sve studente.
Unutar klase, statičkom polju se može pristupiti direktno. Međutim, kada mu se pristupa
van klase – eksterno, jedini način pristupa je korišćenjem imena klase. Na primer, kada
bismo želeli da na standardnom izlazu prikažemo vrednost polja brojStudenata:
3/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
System.out.println(Student. brojStudenata);
Statičkom polju klase se može pristupiti i preko reference nekog od objekata te klase, ali bi
to trebalo izbegavati, pošto se može steći utisak da je statičko polje član objekta. U
drugom sliučaju, moglo bi se desiti da referenca objekta referencira null vrednost. Tada bi
Java ispalila izuzetak.
Polja čija se vrednost nakon inicijalizacije ne može menjati deklarisana su kao final. To
su konstante, pa svaki pokušaj dodeljivanja vrednosti ovakvom polju, osim u inicijalizaciji,
dovodi do greške. Dakle, final definiše nepromenljivost svojstva klase (u smislu
statičnosti) ili objekta.
Ako polje koje je deklarisano kao final nema inicijalizator, zove se blank final. Ova se
polja moraju inicijalizovati kada i klasa, odnosno kada je objekat klase potpuno konstruisan
(u suprotnom slučaju kompajler će prijaviti grešku).
Kontrola pristupa
Identifikatori pristupa:
U programskom kodu Jave, novi objekti se prave korišćenjem ključne reči new. Da bi se
pozvao mehanizam pravljenja objekata, potrebno je zadovoljiti neke uslove koji se tiču
deklaracije promenljivih koje će referncirati nove objekte. Postavlja se pitanje koji su to
uslovi i koji je mehanizam zadužen za pravljenje objekata?
4/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Da bismo odgovorili na ova pitanja, analiziraćemo sledeći kod, koji odgovara pravljenju
novih objekata tipa “Student”:
student1.mentor = student2;
student2.mentor = null;
U ovom kodu napravljena su dva nova objekta tj, analogno realnoj situaciji, na
manifestaciju su prijavljena dva nova studenta. Zatim su im inicijalizovani podaci. Broj
studenata se povećava analogono prijavljivanju novih studenata na manifestaciju.
Primetićemo da ovo povećanje sada programer unosi ručno, a logično bi bilo da postoji
sautomatizovani mehanizam koji bi ovu proceduru izvršavao svaki put kada se napravi novi
objekat. Uskoro će i ovaj problem biti rešen, ali, za sada, hajde da objasnimo detaljnije
navedeni kod.
Kada se objekat napravi ključnom rečju new, navodi se tip objekta koji se pravi i svi argumenti njegove
konstrucije. Java runtime system alocira dovoljno memorije za čuvanje objekta i zatim ga inicijalizuje i
vraća referencu na novonastali objekat. Ukoliko izvršni sistem ne može da pronađe dovoljno prostora u
memoriji da napravi novi objekat, pokrenuće garbage collector-a da bi pokušao da oslobodi prostor, a ako
to ne uspe da obezedi dovoljno prostora, Java će ispaliti OutOfMemmoryError. Objekte ne bi trebalo
nikada eksplicitno brisati, pošto postoji mehanizam sakupljača đubreta, tako da, ukoliko programer ne
treba neki objekat, potrebno je da prestane da ga referencira, a automatizovan sistem će sam osloboditi
memorijski prostor koji je on zauzeo.
U ovom primeru, prvo smo napravili novi objekat, pa smo njegovim poljima dodavali
vrendnosti. Zatim smo ručno podešavali statičko polje klase, koje označava broj studenata
koji učestvuju na manifestaciji. Uslov da objekat bude napravljen i referenciran jeste da je
jasno i tačno deklarisan tip reference koja će ga primiti. Time je odgovoreno na prvo
pitanje ovog dela. Odgovor na drugo pitanje, koji je mehanizam zadužen za pravljenje
novih objekata je: konstruktor.
5/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Konstruktori i inicijalizacija
Kada se u Javi stvori novi objekat, on ima neko svoje inicijalno stanje. Polja objekta mogu
se inicijalizovati prilikom njihovog deklarisanja, a mogu da prihvate i svoje podrazumevane
vrednosti. Ovo je ponekad dovoljno da obezbedi potrebno i ispravno inicijalno stanje. Neke
inicijalizacije se ne mogu izraziti običnim dodelama vrednosti.
class Student {
int index;
String ime;
Student mentor;
public Student() {
brojStudenata++;
}
}
Deklaracija konstruktora sastoji se od imena tipa (klase), iza koga u zagradi dolazi lista
argumenata, koja može biti prazna (to su parametri konstruisanja objekata) i telo naredbi
unutar vitičastih zagrada. Konstruktori nisu članovi klase i to bi trebalo imati u vidu, zbog
nasleđivanja.
Konstruktor klase Student ne uzima argumente konstrukcije, ali ima veoma važnu
funkciju, da po automatizmu povećava broj učesnika na manifestaciji, svaki put kada se
inicijalizuje novi objekat koji predstavlja učesnika. Eventualne greške prilikom povećavanja
broja su izbegnute prebacivanjem odgovornosti na klasu Student. Pošto je trenutno
konstruktor klase jedini koji menja vrednost polja brojStudenata, mogli bi smo mu
dodati modifikator private. Ovime bismo obezbedili da je pristup ovom polju moguć samo
unutar klase.
6/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Sada smo obezbedili da, kada new vrati referencu na objekat, njegova polja budu
inicijalizovana parametrima koje smo prosledili kao argumente konstruktoru. Pravljenje
objekta je olakšano:
Bitno je napomenuti da klasa može imati neograničen broj konstruktora, dok god im se
razlikuju argumenti konstrukcije. To znači da oba konstruktora klase Student koja smo
napravili mogu ostati u klasi. Programer će, u zavisnosti od situacije, koristiti odgovarajući
konstruktor.
Konstruktori bez argumenata, kao prvi konstruktor klase Student koji smo implementirali,
zovu se no-arg konstruktori. Ukoliko se eksplicitno ne implementira konstruktor prilikom
pisanja klase, Java ima podrazumevani no-arg konstruktor, koji se automatski obezbeđuje,
a ne izvršava nikakve naredbe. Njegova dostupnost, u smislu prava pristupa, ista je kao
dostupnost klase. Drugi oblik konstruktora može biti copy konstruktor, koji kao argument
prima postojeći objekat klase i kopira vrednosti njegovih polja u polja novonastalog
objekta, što nije česta pojava u Javi, pošto je zastupljeniji način kopiranja objekata
pozivanje metode clone().
7/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
class Student {
int index;
String ime;
Student mentor;
{
index = 0;
ime = "Nepoznat učesnik";
mentor = null;
}
public Student() {
brojStudenata++;
}
}
Sada će se, pre izvršavanja konstruktora, izvršiti naredbe u inicijalizacionom bloku, koje će
postaviti polja na definisane podrazumevane vrednosti, kao što je "Nepoznat učesnik".
Inicijalizatore mogu imati i statička polja klase. Njih obezbeđujemo u bloku za statičku
inicijalizaciju, koji je identičan prethodno definisanom bloku, samo je deklarisan kao
static, pa može referencirati isključivo statičke elemente klase:
static {
brojStudenata = 15;
}
8/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Referenca “this”
Kada nekoj metodi ili konstruktoru prosledimo argument koji ima svoj naziv, poput
argumenta ime, njegov naziv je njegova referenca u lokalnom smislu (to važi isključivo
unutar tela metode, tj. konstruktora). Pošto je ime referenca na neki prosleđen niz
karaktera, polju ime objekta koji pravimo ne možemo pristupiti ovim nazivom. Zato
koristimo referencu na tekući objekat i pozivamo njegovo polje.
Hajde da sada pomenemo još jedno bitno svojstvo konstruktora. Naime, jedan konstruktor
može pozvati izvršenje drugi konstruktor, korišćenjem naredbe this(). Ovo mora biti prva
stavka u konstruktoru, a proces njegovog zvanja je eksplicitno pozivanje konstruktora.
Ovim načinom se može pozvati bilo koji drugi konstruktor u klasi, naravno sa
odgovarajućim argumentima.
Vratimo se na primer klase Student. Napravili smo dva konstruktora, od kojih oba kao
prvu naredbu imaju brojStudenata++. Korišćenjem eksplicitnog pozivanja konstruktora,
drugi konstruktor bi pozivao tu naredbu pozivanjem prvog konstruktora:
public Student() {
brojStudenata++;
}
Napomenućemo još jednom, eksplicitno pozivanje konstruktora mora biti prva naredba u
konstruktoru koji ga poziva.
9/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Metode
Metode klase obično sadrže kod, koji razume stanja objekta i njima manipuliše. Metode,
oslanjajući se na trenutno stanje objekta i poznate ulaze, teže da objekat kao sistem
prevedu u novo stanje. Istina je da neke klase imaju javna ili zaštićena polja nad kojima
programeri mogu direktno raditi, međutim, praksa je pokazala da većina vrednosti zahteva
obradu pre prikazivanja. Ovu računarsku obradu obezbeđuje implementacija metoda.
Ovakav ispis omogućava nam da u željenom formatu ispišemo na standardni izlaz podatke
o studentu učesniku, koji uključuju njegovo ime, broj indeksa i ime i br. indeksa mentora:
Sada kada je ispisiNaEkran() metoda, tj. ustaljeno ponašanje objekata klase Student,
svaki objekat može izvršiti operacije u njoj navedene pozivanjem njenog imena:
student.ispisiNaEkran();
Obratimo pažnju sada na deklaraciju metode. Sastoji se iz dva dela: zaglavlja i tela.
Zaglavlje metode se opciono sastoji iz skupa modifikatora koji prehode tipu rezultata,
potpisu (imenu metode) i, opciono, klauzule throws, o kojoj će biti reči kasnije u toku
kursa.
10/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Potpis metode sastoji se iz imena metode zagrada. Unutar zagrada navode se argumenti
koje metoda prima, ukoliko postoje. To je lista tipova podataka koje metoda prima na
obradu kao ulaz. Sve metode moraju sadržati tip povratne vrednosti (rezultata) i potpis. U
telu metode, unutar vitičastih zagrada, pišu se programske naredbe.
Modifikatori metoda:
- modifikatori pristupa (javne, privatne, zaštićene)
- abstract (telo metode nije definisano)
- static (vezano za klasu, ne za određene njene instance)
- final (može se zaobići u podklasi)
- synchronized (sinhronizacija niti)
- native (kod pripada nekom drugom programskom jeziku)
- strictftp (striktna pravila pokretnog zareza)
Statičke metode pozivaju se u ime cele klase, ne u ime neke određene instance, tj. objekta
klase. Ovakve metode mogu pristupiti jedino statičkim poljima klase i drugim statičkim
metodama. Ostalim članovima se mora pristupiti pomoću reference objekata, a u statičkim
metodama ne postoji referenca this. U primeru klase Student, postoji statičko polje
brojStudenata, koje je javno. Ukoliko bi ovo bilo privatno polje, morala bi postojati
metoda koja mu pristupa, kako bi se sadržaj polja mogao čitati van klase. Ovo bi
obezbedila implementacija jedne statičke metode.
Pogledamo sada kako smo pozvali metodu ispisiNaEkran() u prethodnom primeru. Prvo
smo ispisali referencu na objekat za koji želimo da realizujemo određeno ponašanje, pa
smo, znajući potpis metode, pozvali i samo ponašanje na realizaciju. Na primer,
pogledajmo metodu za ispis na standardnom izlazu:
System.out.println("Ispis na ekranu!");
Prvo je referenciran statički objekat out, koji pripada klasi System, a zatim je pozvana
metoda println(), kojoj je kao argument prosleđen jedan String objekat.
Metode se ne mogu deklarisati promenljivim beojm parametara, mada joj se kao argument
može proslediti niz objekata. Svaki parametar unutar zagrada metode mora biti deklarisan
u smislu tipa. Pre pozivanja metode, programer je svestan potpisa metode, kao i broja i
tipova argumenata koje ona prima kao ulaz. Takođe, svestan je i tipa rezultata koji želi da
metoda vrati nakon obavljana operacija navedenih u njenom telu. Dakle, on mora da
obezbedi tačno određen broj argumenata određenog tipa kada metodu poziva, a da njen
rezultat upisuje u promenljivu koja je tipa povratne vrednosti metode.
Tip rezultata metode može biti primitivni tip (vrednosni) ili referentni tip. Ukoliko metoda
ne daje nikakvu povratnu vrednost, deklarisana je kao void.
11/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Vrednost koju vraćamo kao rezultat naredbom return mora po tipu odgovarati
deklarisanom rezultatu (u ovom slučaju double).
Metoda uvek kao rezultat vraća isključivo jednu vrednost čiji je tip naveden u deklaraciji
metode. Rekli smo da ovo može biti ili vrednosni ili referentni tip podatka. Ukoliko je
potrebno vratiti više podataka, ovo može biti učinjeno deklaracijom da je rezultat metode
niz ili lista objekata, koji sadrže rezultate.
Za sam početak, potrebno je razjasniti značenje ovih pojmova. Vrednosni tip podatka je
onaj, gde podatak pokazuje na određenu vrednost u memoriji, koja je određenog tipa
(prost tip podatka). U slučaju referentnog tipa, podatak referencira neki objekat u
memoriji, tj. pokazuje na njegovu adresu u memoriji, a ne na konkretnu vrednost.
U slučaju kada metoda kao argument primi neki vrednosni tip, prenosi se njegova vrednost
metodom kopiranja, tako da, unutar tela metode, ne vrši se direktan uticaj na prosleđenu
promenljivu već na njenu kopiju. U slučaju referentnih tipova, ne prenosi se vrednost nego
referenca, tako da se promenljiva može direktno referencirati.
12/13
Udruženje studenata informatike Fakulteta Organizacionih Nauka u Beogradu
Kada bismo metodi koja računa kvadrat prosledili neku inicijalizovanu promenljivu, unutar
metode vršile bi se operacije nad njenom kopijom:
Ukoliko metodi prosledimo neku referencu, unutar tela metode možemo samu referencu
menjati, a da time ne utičemo na sam objekat na koji ona pokazuje (referencira). Međutim,
ukoliko upotrebimo referencu da promenimo atribut objekta, ova će promena biti trajna:
Zadatak
Klase definisane u prošlom zadatku projektovati i zapisati u kodu programskog jezika Java.
Implementirati metode, inicijalizovati polja i napraviti test primere.
Zadatak napisati kao Word dokument ili PDF dokument na ne više od pet stranica A4
formata teksta ili slike (dijagrama) i poslati na mail sa attachment-om na adresu:
kursevi@fonis.rs sa subject-om JAVA-ZADATAK-2. U tekstu attachment -a navesti ime,
prezime i broj indeksa.
13/13