You are on page 1of 237

dr Nenad Jovanović

OBJEKTNO ORIJENTISANO
PROGRAMIRANJE

sa praktikumom

Visoka poslovna škola - Blace


2012. godin
Objektno orijentisano programiranje
dr Nenad Jovanović

Recenzent:
Prof. dr Ranko Popović

Izdavač:
Visoka poslovna škola - Blace

Za izdavača:
dr Ružica Stanković, direktor

Priprema i računarska obrada:


dr Nenad Jovanović

Tiraž: 200 primeraka

Štampa: SIGRAF kruševac

Sva prava zadržana. Ni jedan deo ove knjige ne može biti reprodukovan,
presnimavan ili prenošen bilo kojim sredstvom, elektronskim,
mehaničkim, za kopiranje, za snimanje, ili na bilo koji drugi način bez
prethodne saglasnosti Izdavača.

ISBN 978-86-7544-089-5

ii
Sadržaj

1. UVOD .................................................................................. 1
1.1. Programske paradigme............................................................................. 2

1.2. Java arhitektura ......................................................................................... 7


2. KLASE I OBJEKTI ................................................................. 15
2.1. Deklarisanje klase.................................................................................... 17

2.2. Pravljenje objekata .................................................................................. 19

2.3. Polja .......................................................................................................... 19

2.4. Metode ...................................................................................................... 28

2.5. Osnovne kontrolne strukture ................................................................. 33

2.6. Konstruktori ............................................................................................. 41


3. OBJEKTNO ORIJENTISANO MODELOVANJE ................... 47
3.1. UML ........................................................................................................... 47

3.2. Strukturno modelovanje ......................................................................... 50

3.3. Modelovanje ponašanja .......................................................................... 57


4. NIZOVI............................................................................... 63
4.1. Promenljiva niza ...................................................................................... 64

4.2. Kreiranje niza ........................................................................................... 64

4.3. Smeštanje podataka u niz....................................................................... 65

4.4. Obrada elemenata niza ........................................................................... 67

4.5. Operacije sa nizovima ............................................................................. 68

iii
4.6. Objekat String .......................................................................................... 73
5. ENKAPSULACIJA ............................................................ 87
5.1. Paketi ........................................................................................................ 87

5.2. Modifikatori pristupa ............................................................................... 93


6. UPOTREBA KLASA ......................................................... 99
6.1. Okupljanje ................................................................................................ 99

6.2. Nasleđivanje........................................................................................... 104

6.3. Razlika između nasleđivanja i kompozicije ........................................ 119


7. POLIMORFIZAM .................................................................. 121
7.1. Uvod u polimorfizam ............................................................................. 121

7.2. Dinamičko razrešavanje poziva metode.............................................. 126

7.3. Proširivanje programa........................................................................... 129

7.4. Polimorfizam i konstruktori .................................................................. 132


8. INTERFEJSI ......................................................................... 137
8.1. Deklarisanje interfejsa .......................................................................... 138

8.2. Implementiranje interfejsa .................................................................... 138

8.3. Nasleđivanje interfejsa.......................................................................... 142

8.4. Razlika između apstraktne klase i interfejsa ...................................... 146


9. IZUZECI................................................................................ 147
9.1. Vrste izuzetaka....................................................................................... 149

9.2. Obrada izuzetka ..................................................................................... 152

9.3. Objekti klase Throwable ....................................................................... 155

9.4. Definisanje izuzetka............................................................................... 156


PRAKTIKUM ............................................................................ 159
EVIDENCIJA VEŽBI................................................................. 161

iv
VEŽBA 1. - JAVA RAZVOJNO OKRUŽENJE ......................... 163
VEŽBA 2. - INTEGRISANO RAZVOJNO OKRUŽENJE –
NETBEANS .............................................................................. 173
VEŽBA 3. - ELEMENTI JAVE .................................................. 181
VEŽBA 4. - PROJEKTOVANJE KLASE KOCKA.................... 187
VEŽBA 5. - OBJEKAT NIZ I STRING ...................................... 193
VEŽBA 6. - PROJEKTOVANJE KLASE STUDENT ................ 205
VEŽBA 7. – KLASA BANKA ................................................... 211
LAB. VEŽBA 8. - NASLEĐIVANJE I POLIMORFIZAM ........... 217
LAB. VEŽBA 9. - PRAVLJENJE GRAFIČKOG KORISNIČKOG
INTERFEJSA U NETBEANS-U ............................................... 221
LITERATURA........................................................................... 227

v
vi
Lista programskih primera

Primer 2.1. Casovnik.java......................................................... 18


Primer 2.2. Casovnik.java......................................................... 26
Primer 2.3. Casovnik.java......................................................... 26
Primer 2.4. Krug.java ................................................................ 27
Primer 2.5. Casovnik.java......................................................... 28
Primer 2.6. Casovnik.java......................................................... 29
Primer 2.7. ProsledjivanjeArgumenata.java ........................... 31
Primer 2.8. KolikoJeSati.java ................................................... 32
Primer 2.9. Casovnik.java......................................................... 35
Primer 2.10. Metoda odrediDan()............................................. 37
Primer 2.11. KolikoJeSati.java ................................................. 38
Primer 2.12. Casovnik.java....................................................... 43
Primer 2.13. Soba.java.............................................................. 44
Primer 2.14. KolikoJeSati.java ................................................. 45
Primer 4.1. Obrada elemenata niza u for petlji ....................... 67
Primer 4.2. Obrada elemenata niza u for-each petlji .............. 67
Primer 4.3. KopiranjeNiza.java................................................. 68
Primer 4.4. PoredjenjeNzova.java............................................ 69
Primer 4.5. SortiranjeNiza.java ................................................ 70
Primer 4.6. PretrazivanjeNiza.java ........................................... 71
Primer 4.7. SpajanjeZnakovnihNizova.java ............................ 75
Primer 4.8. PoredjenjePromenljivih.java................................. 76
Primer 4.9. PoredjenjeStringova.java...................................... 77
Primer 4.10. StringElementi.java ............................................. 78

vii
Primer 4.11. PretrazivanjeZnakovnogNiza.java ...................... 80
Primer 4.12. SortiranjeStringova.java ..................................... 81
Primer 4.13. IzdvajanjePodniza.java........................................ 82
Primer 4.14. IzdvajanjePodniza1.............................................. 83
Primer 5.1. Zaposleni.java........................................................ 89
Primer 5.2. ZaposleniPrimer.java ............................................ 90
Primer 5.3. Casovnik.java......................................................... 95
Primer 5.4. Kafa.java................................................................. 96
Primer 5.5. SkuvajKafu.java ..................................................... 97
Primer 5.6. Zaposleni.java........................................................ 97
Primer 6.1. PC.java ................................................................. 100
Primer 6.2. RacunarskaMreza.java ........................................ 101
Primer 6.3. RacunarskaMreza1.java ...................................... 102
Primer 6.4. Zaposleni.java...................................................... 107
Primer 6.5. Direktor.java......................................................... 108
Primer 6.6. ProizvodniRadnik.java ........................................ 109
Primer 6.7. ZaposleniPrimer.java .......................................... 110
Primer 6.8. Dva.java ................................................................ 112
Primer 6.9. RedosledZavisnostiKonstruktora.java .............. 113
Primer 6.10. Zivotinja.java...................................................... 117
Primer 6.11. Lav.java .............................................................. 117
Primer 6.12. Krava .................................................................. 118
Primer 6.13. ZivotinjaPrimer.java .......................................... 118
Primer 7.1. GeomObjekat.java ............................................... 122
Primer 7.2. Krug.java .............................................................. 122
Primer 7.3. Pravougaonik.java ............................................... 122
Primer 7.4. Povrsina.java ....................................................... 123
Primer 7.5. Povrsina1.java ..................................................... 124

viii
Primer 7.6. Povrsina2.java ..................................................... 125
Primer 7.7. X.java .................................................................... 127
Primer 7.8. Y.java .................................................................... 127
Primer 7.9. Z.java .................................................................... 127
Primer 7.10. RazresavanjePoziva.java .................................. 128
Primer 7.11. ProsirivanjePrograma.java ............................... 129
Primer 7.12. KafaZaPoneti.java.............................................. 132
Primer 7.13. CrtajKrug.java .................................................... 134
Primer 8.1. FaktorKonverzije.java ......................................... 139
Primer 8.2. PrimerKonvertor.java .......................................... 139
Primer 8.3. PrimerKonvertor.java .......................................... 140
Primer 8.4. Konvertor.java ..................................................... 140
Primer 8.5. KonvertorValuta.java........................................... 141
Primer 8.6. KonvertorValutaPrimer.java ............................... 141
Primer 8.7. Konvertor.java ..................................................... 142
Primer 8.8. Zivotinja.java........................................................ 143
Primer 8.9. DomacaZivotinja.java .......................................... 144
Primer 8.10. DivljaZivotinja.java ............................................ 144
Primer 8.11. MozeDaCuva.java .............................................. 144
Primer 8.12. MozeDaLovi.java................................................ 144
Primer 8.13. MozeDaTrci.java ................................................ 144
Primer 8.14. Pas.java .............................................................. 144
Primer 8.15. Vuk.java .............................................................. 145
Primer 8.16. Primer.Zivotinje.java ......................................... 145
Primer 9.1. PrimerFinally.java ................................................ 154
Primer 9.2. MojIzuzetak.java .................................................. 157
Primer 9.3. PrimerMojIzuzetak.java ....................................... 157
Primer 9.4. PrimerMojIzuzetak1.java ..................................... 158

ix
x
Uvod

POGLAVLJE 1

1. UVOD

Da bi računarski sistem uspešno funkcionisao neophodno je definisati program


rada računara. Računarski program, koji govori računaru koje operacije treba
da izvrši i nad kojim podacima, sastoji se od pojedinačnih instrukcija koje su
smeštene u operativnoj memoriji računara.
Računarski programi se pišu pomoću programskih jezika. Programski jezici su
u svom razvoju prošli kroz nekoliko razvojnih faza.
Jezici prve generacije su mašinski jezici. Instrukcije mašinskog jezika su
binarno kodirane. Program pisan mašinskim jezikom, a koji je smešten u
operativnoj memoriji računara i koji računar jedino razume naziva se mašinski
program računara. Termin ”мašinski jezik” ne odnosi se na jedinstven jezik.
Svaki računar, odnosno familija računara, ima svoj mašinski jezik koji koristi
instrukcije prilagođene tom hardware-u. Zbog toga se kaže da je mašinski jezik
zavisan od mašine.
Jezici druge generacije su simbolički jezici. Da bi se računarski program
približio korisniku i postao razumljiviji uvodi se pojam simboličkog programa.
Binarni kodovi u instrukcijama mašinskog jezika zamenjuju se simbolima i na
taj način se dobijaju instrukcije simboličkog jezika. Program pisan na
simboličkom jeziku računara je razumljiviji, ali on ipak predstavlja apstrakciju
mašinskog jezika, koji prati logiku rada mašine i nije podesan i prilagođen za
predstavljanje rešenja problema koji bi trebalo da se rešavaju na računaru.
Računar ne razume instrukcije koje nisu pisane u mašinskom jeziku, tako da je
potreban specijalan program koji će prevesti instrukcije somboličkog jezika u
instrukcije mašinskog jezika. Taj program – prevodilac se naziva assembler.
Jezici prve i druge generacije bili su karakteristični po veoma neefikasnim
alatima za pisanje programskog koda. Zahtevali su veoma dug kod za veoma
jednostavne probleme.

1
Uvod

Jezici treće generacije su viši programski jezici, koji se uvode da bi se model


računarskog programa približio modelu rešenja problema. Viši programski
jezici omogućavaju da se struktura rešenja problema preslika u strukturu
računarskog programa. Viši programski jezici znatno pojednostavljuju
programiranje. Broj instrukcija u programu pisanom nekim višim programskim
jezikom je znatno manji od broja instrukcija u programu pisanom na
simboličkom jeziku programiranja. Vrlo bitna prednost viših programskih jezika
u odnosu na mašinski i simbolički jezik programiranja je u tome što oni ne
zavise od hardverskih karakteristika mašine na kojoj se izvršavaju, ali da bi se
oni izvršili neophodno je da postoje posebni prevodioci (kompajleri) ili
interpretatori koji prevode program pisan na višem programskom jeziku u
mašinski jezik. Iz ovog sledi i osnovni nedostatak viših programskih jezika u
odnosu na simbolički jezik, a to je brzina izvršavanja i optimalan kod.
U jezicima četvrte generacije kraćim komandama zamenjene su brojne
instrukcije. U budućnosti biće moguće programirati računare koristeči prirodne
jezike. Ali čak i tada, ti prirodni jezici moraće da se prevedu na mašinski jezik.

1.1. Programske paradigme

Paradigma je obrazac, model po kome se nešto gradi ili stvara. U naučnoj


teoriji, paradigma je najopštiji model po kojem se grade pojedini principi.
Model je način formalnog predstavljanja nekog sistema ili podsistema. Model
može biti matematički i u tom slučaju on se posmatra kao skup osobina
sistema kao što su njegove funkcionalne osobine ili fizičke dimenzije. Model
može biti i konstruktivan i u tom slučaju on definiše procedure koje oponašaju
skup osobina datog sistema. Konstruktivni model se često koristi za opisivanje
ponašanja sistema kao odziva na spoljne stimulanse.
Sam process rešavanja nekog problema na računaru se svodi na modelovanje,
odnosno na nalaženje pogodne apstrakcije sa kojom računar može da radi.
Problem može da se reprezentuje na različite načine (model problema), ali
računar (model mašine) ne može da obradi svaku reprezentaciju problema.
Obzirom da postoji ogroman jaz između modela mašine i modela problema
nastale su različite programske paradigme, koje definišu načine modelovanja
problema, tako da oni mogu da se preslikaju na model mašine.
Objektno orijentisano programiranje (Object-oriented programming) je jedna od
programskih paradigmi. Primeri drugih programskih paradigmi su strukturirano
programiranje (structured programming), imperativno (imperative
programming) i deklarativno programiranje (declarative programming).
Prva naučno i teoretski zasnovana paradigma programiranja naziva se
strukturirano programiranje. Strukturirano programiranje predstavlja tehniku
programiranja koja je ograničena striktnim pravilima.

2
Uvod

Strukturirano programiranje definiše način razvoja računarskih programa u


koracima preciziranja, pri čemu se koristi konačan broj kontrolnih struktura koje
su hijerarhijski ugneždene u strukturiranom programu. Strukturirani programi
isključuju nekontrolisane bezuslovne skokove.
Da bi program bio strukturiran on mora da bude pravilan. Pravilan program je
program koji nema beskonačne petlje i izolovane programske segmente i koji
ima jednu ulaznu i jednu izlaznu liniju.
Svaki logički deo pravilnog programa takođe mora da zadovolji uslov da ima
samo jednu ulaznu i jednu izlaznu liniju.
Svaki strukturirani program može se predstaviti pomoću petlje unutar koje se
nalazi selekcija sa onoliko paralelnih grana koliko ima čvorova u dijagramu
toka.
Po strukturiranoj teoremi svaki pravilan program može se transformisati u
formalno strukturirani program uz korišćenje tri osnovne kontrolne strukture:
 sekvence,
 selekcije i
 iteracije.
Ova teorema pruža mogućnost da se programiranje svede na rad sa
ograničenim brojem kontrolnih struktura.
Primenom tehnike strukturiranog programiranja postižu se sledeći ciljevi:
 minimizacija broja grešaka tokom razvoja programa,

 minimizacija rada potrebnog za razvoj softvera i

 minimizacija troškova održavanja programa.

Imperativno programiranje je programska paradigma koja opisuje


programiranje kao izraze koji menjaju stanje programa. Imperativni programi se
mogu posmatrati kao niz naredbi koje računar treba da izvršiti. Proceduralno
programiranje je česta metoda izvršavanja imperativnog programiranja, pa se
ova dva termina često koriste kao sinonimi.
Model problema zasnovan na proceduralnom programiranju sastoji se od
koraka koji definišu šta treba da se uradi i kada treba da se uradi. Rešenje
problema se razlaže na delove, koji se predstavljaju procedurama. Model
problema, u proceduralnim jezicima, predstavlja apstrakciju mašine na kojoj se
program izvršava i predstavlja se u prostoru rešenja. Programer razmišlja o
rešenju a ne o problemu. Posledica toga je da je napisan kod nečitak i da ga je
vrlo teško ispravljati i dodavati nove mogućnosti. Model se predstavlja
algoritmom bilo u grafičkom obliku ili pomoću pseudo jezika, a zatim se kodira
nekim proceduralnim jezikom.

3
Uvod

Proceduralni jezici (C, Pascal, Fortran ...) predstavljaju apstrakciju mašinskog


jezika koji predstavlja apstrakciju mašine na kojoj se izvršava. Njihova primarna
apstrakcija zahteva da se prilikom programiranja razmišlja iz ugla logičke
strukture računara, a ne iz ugla problema koji se rešava.
Deklarativno programiranje je paradigma programiranja koja izražava logiku
izračunavanja bez opisivanja svoje kontrole toka. Deklarativan program je
program koji opisuje šta izračunavanje treba da izvrši, a ne kako treba da se
obavi. Mnogi jezici primenom ovog stila pokušavaju da smanje ili eliminišu
neželjene efekte opisivanjem šta program treba da ostvari, a ne kako da se to
ostvari. To je u suprotnosti sa imperativnim programiranjem koje zahteva
izričito određeni algoritam. Deklarativno programiranje često smatra programe
kao teoriju formalne logike, a izračunavanja kao odbitke u tom logičkom
prostoru. Deklarativno programiranje je posebnog značajno u poslednje vreme,
pošto u velikoj meri pojednostavljuje pisanje paralelnih programa. Deklarativno
programiranje uključuje:
 Logičko programiranje i
 Funkcionalno programiranje.
Logičko programiranje je programska paradigma koja se zasniva
na matematičkoj logici. Glavni predstavnik jezika logičkog programiranja je
Prolog.
Funkcionalno programiranje tretira program kao evaluaciju matematičkih
funkcija i izbegava stanja i promenljive podataka. Ono naglašava primenu
funkcija, kao suprotnost stilu imperativnog programiranja koje naglašava
promene stanja. Funkcionalni jezici su APL, Erlang, Haskell, Lisp ...
Objektno orijentisano programiranje - OOP je način da se konceptualizuje
jedan računarski program. Naime o programu možemo razmišljati kao o jednoj
listi instrukcija, koje govore računaru šta da radi, a možemo i razmišljati kao o
velikom broju malih programa (objekata) koji reaguju na specifične događaje
inicirane akcijama korisnika.
Prvi način se naziva procesno orijentisani model, a drugi objektno orijentisani
model. Kod procesno orijentisanog modela program se posmatra kao niz
naredbi koje rade sa podacima. Ovaj model je primenjen kod proceduralnih
jezika kao čto su C i Pascal, ali kada program postane velik i složen ovaj
model ne daje dobre rezultate.
Osnovni problem je što se programer koncetriše na rešenje. Da bi se rešenje
predstavilo pomoću proceduralnih programskih jezika, koji predstavljaju
apstrakciju mašinskog jezika, programer treba da uspostavi vezu između
modela mašine, na kojoj se program izvršava, i modela problema koji se
rešava. Ovakav način predstavljanja je bolji što se tiče mašine, jer program
preslikava logiku rada računara u prostor rešenja problema, ali je zato stran
čovekovom načinu razmišljanja.
Kada program preraste određen broj programskih linija javljaju se brojni
problemi:

4
Uvod

 nemoguće je pratiti tok njegovog izvršavanja,

 ispravljanje grešaka je otežano a

 dodavanje novih funkcija neproduktivno.

Objektno orijentisani model omogućava orijentaciju programa na podatke


(objekte). Program se posmatra kao jedan niz objekata koji zajedno funkcionišu
na prethodno definisanim principima u cilju ostvarenja zadatka. Ovaj model
pruža niz organizacijskih prednosti u odnosu na tradicionalni. Te prednosti su:
 model je razumljiviji,

 lakše je lokalizovati i otkloniti greške i

 Lakša je faza eksploatacije programa.

Osnovni elementi objektnog modela su:


 Apstrakcija

 Enkapsulacija

 Nasleđivanje

 Polimorfizam

Apstrakcija je pojednostavljen opis nekog sistema, napravljen tako da naglasi


bitne karakteristike, a da ignoriše sve za dati slučaj nebitne osobine.
Dakle, realan pojam se apstrahuje i predstavlja se objektom, birajući samo one
osobine objekta koje su za taj nivo apstrakcije potrebne. Ostale osobine se
ignorišu.
Hijerarhijsko apstrahovanje omogućava da se složeni sistemi organizuju po
slojevima, razdvajajući ih na celine sa kojima je lakše raditi.
Podaci se iz tradicionalnih programa mogu apstrakcijom pretvoriti u objekte koji
reaguju na poruke.
Korisnik može proizvoljno da definiše svoje tipove podataka i da ih koristi kao i
ugrađene tipove podataka.
Ako, na primer, modelujemo neki hardverski sistem možemo definisati tipove:
 Računar

 Procesor

 Disk

5
Uvod

 Memorija...

Korisnik ovih novih tipova ne mora biti i njihov autor, dovoljno je da zna da ih
upotrebi na propisani način.
Enkapsulacija predstavlja skrivanje detalja implementacije objekta od
korisnika objekta. Korisniku se dozvoljava pristup objektu samo kroz jasno
definisan interfejs objekta. Enkapsulacijom se smanjuje međuzavisnost
komponenata, tako što se ne dozvoljava da od internih osobina nekog objekta
zavisi ostatak sistema.
Enkapsulacija se ostvaruje u objektno orijentisanom programskom jeziku
pomoću klase. Klasa definiše strukturu i ponašanja koja su zajednička za skup
objekata. Objekti predstavljaju primerak (instancu) klase, a svaki objekat ima
osobine i ponašanja koja su definisana klasom.
Klasa se sastoji od promenljivih i od metoda. Promenljive definišu stanje
objekata a metode njihova ponašanja. Klase omogućavaju enkapsulaciju tako
što dozvoljavaju da članovi klase (promenljive i metode) mogu biti javni i
privatni.
Javne metode i promenljive su dostupne i van same klase. Privatne metode i
promenljive su dostupne samo iz same klase. Privatne promenljive i privatne
metode su zaštićene i moguće im je pristupiti iz koda van date klase samo
pomoću javnih metoda. To omogućava da se privatni članovi klase menjaju na
kontrolisan i strogo definisan način pomoću unapred definisanog interfejsa. Taj
interfejs je određen javnim metodama. Javne metode grade jedan zaštitni
omotač koji štiti privatne članove klase od spoljnog uticaja, i koji definiše tačno
određen način na koji mogu da se menjaju privatni članovi.
Nasleđivanje se definiše kao redosled apstrakcija.
Nasleđivanje je mehanizam koji omogućava jednoj klasi objekata da nasledi
karakteristike druge klase objekata.
Nasleđivanje objekata predstavlja primer hijerarhije. Nasleđivanje podržava
koncept hijerarhijske klasifikacije, tako da za objekte treba definisati samo one
karakteristike koje ih čine jedinstvenim u klasi.
Tako, na primer, sve geometrijske objekte možemo svrstati u
dvodimenzionalne i trodimenzionalne.
Svi geometrijski objekti imaju osobine kao što su: dimenzije, boja, površina...
Dvodimenzionalni objekti imaju dve dimenzije, oni nasleđuju sve osobine klase
GeometrijskiObjekti i oni su podklasa klase GeometrijskiObjekti a klasa
GeometrijskiObjekti su nadklasa klase DvodimenzionalniObjekti.
Trodimenzionalni objekti imaju tri dimenzije. Oni nasleđuju osobine klase
GeometrijskiObjekti ali se zato razlikuju od objekata klase
DvodimenzionalniObjekti.

6
Uvod

Objekat može biti upotrebljen kao objekat sopstvene klase ili kao objekat
nadklase. Na primer, trougao se može posmatrati kao objekat klase Trougao
ili kao objekat klase Geometrijski objekti. Svi geometrijski objekti imaju
metodu izracunajPovrsinu(). Pozivanje metode izracunajPovrsinu() za neki
objekat, izvršava operaciju izračunavanja površine za specifičan tip, a ne za
osnovni tip bez obzira ako se dati objekat tretira kao osnovni tip. Ova osobina
se naziva Polimorfizam, i ona omogućava da se prilikom programiranja piše
kod koji ne zavisi od specifičnog tipa.
Znači, neki objekat možemo tretirati kao osnovni tip (na primer Trougao
možemo tretirati kao Geometrijsku Figuru) ali se prilikom pozivanje nekog
ponašanja (izracunajPovrsinu()) za taj objekat izvršava ponašanje specifičnog
tipa a ne osnovnog (izračunaće se površina trougla).
Polimorfizam omogućava bolju organizaciju koda i znatno poboljšava čitljivost
koda. Polimorfizam omogućava i pisanje proširivih programa. Programu se lako
mogu dodavati nove mogućnosti, u početnoj fazi izrade programa i kasnije.

1.2. Java arhitektura

Jezik Java je koncipirao tim (J.Gosling, P.Naughton, C.Warth, E.Frank,


M.Sheridan) firme Sun Microsystems, Inc. 1991. godine, kao deo projekta koji
se odnosio na programiranje kućnih aparata. Prvobitno ime jezika bilo je Oak,
razvoj prve radne verzije trajao je 18 meseci, a tek od 1995 ime je promenjeno
u Java.
Osnovni motiv navedenog projekta bila je prenosivost programa sa jedne na
drugu platformu, a jezici kao što su C i C++ nisu uspeli da obezbede
platformsku nezavisnost. Članovi tima su se odlučili da razviju potpuno nov
programski jezik i tako je nastala Java kao jednostavan, brz, pouzdan, efikasan
i platformski nezavisan programski jezik. Razvojem Interneta i njegovih servisa
stvara se dodatni motiv za dalji razvoj Jave, pa se od 1993. godine fokus
projekta premešta sa kućne elektronike na web programiranje.
Osnovne karakteristike Jave su:
 Objektna orijentisanost – moderan OO jezik: klase, nasleđivanje,
polomorfizam, interfejsi.
 Jednostavnost – C/C++ sintaksna sličnost, ali harmoničniji i
jednostavniji OO model.
 Nezavisnost od platforme - isti Java kod može da se izvršava na
različitim platformama.
 Prenosivost – postiže se interpretacijom bajtkoda.
Sigurnost – JVM (Java Virtual Machine) pruža zaštitu od virusa koji bi se
prenosili kroz izvršni kod (firewall)

7
Uvod

 Robusnost – stroga provera tipova, proveravani izuzeci, automatsko


sakupljanje đubreta
Upravljanje memorijom je automatizovano (Garbage Collection)
Korišćenje pointera je limitirano.
 Efiksanost – JIT (Just in time) prevodioci.
 Konkurentnost – bibliotečka podrška programiranju kroz više
programskih niti.
 Distribuiranost – bibliotečka podrška za RMI (Remote Method
Invocation) i servlete.
 Komponentizacija – Java Beans i Enterprise Java Beans.
Java arhitektura obuhvata četiri tehnologije koje su zasebno razvijane od
strane Sun Microsystems-a. Ove četiri tehnologije su:
 Programski jezik Java
 Class format Java fajlova
 Java API (Application Programming Interface)
 Java virtuelna mašina
Programer piše program na Java programskom jeziku. Izvorna verzija
programa se smešta u datoteku sa ekstenzijom java (Primer.java). Izvorni
program se kompajlira pomoću Java (javac Primer.java) kompajlera i dobija
se bajtkod u obliku Java class datoteke (Primer.class). Java class datoteka
se prenosi kroz mrežu i izvršava se pomoću Java virtuelne mašine (java
Primer) (slika 1.1.).

Slika 1.1.

8
Uvod

Java class datoteka ima sledeće osobine:


 program je mali,
 sigurnost i
 nezavisnost od platforme na kojoj se izvršava.
Kada programer piše program u Java programskom jeziku, on se obraća
sistemskim resursima, pozivanjem metoda klasa koje čine Java API.
Zajedno Java API i Java virtuelna mašina čine Java platformu.
Programi pisani na drugim programskim jezicima moraju da se kompajliraju,
čime se izvorni programi prevode u mašinski program, koji može da se
izvršava na navedenoj platformi. Java programi, nakon kompajliranja se
prevode u Java bajtkod. Da bi Java bajtkod mogao da se izvrši na nekom
računaru potrebna je Java virtuelna mašina. Java virtuelna mašina je jedan
apstraktni računar, softverski realizovan, na kome se izvršavaju Java
bajtkodovi. Java virtuelna mašina je implementirana za različite operativne
sisteme kao što su: Windows, Solaris, Mac OS, Linux.
Programi pisani u Java programskom jeziku mogu da se izvršavaju na bilo kom
sistemu na kome postoji Java platforma i ne zavise od operativnog sistema niti
od arhitekture procesora sistema na kome se izvršavaju (slika 1.2.).

9
Uvod

Slika 1.2.

Java virtuelna mašina učitava Java class datoteke iz programa koje piše
programer i iz Java API-ja pomoću Java loader-a. Tako učitan Java bajtkod
se izvršava pomoću izvršne mašine (slika 1.3.).

10
Uvod

Slika 1.3

Java programi mogu biti Java aplikacije ili Java apleti.


Aplikacije su klasični programi koji se distribuiraju na konvencionalan način,
pokreću pod operativnim sistemom računara (pod kojim je instalirana JVM).
Apleti su (uglavnom mali) programi koji se distribuiraju preko Interneta,
odnosno web-a, kao delovi HTML stranica i pokreću u okviru web čitača
(browser).
Osnovne razlike između Java aplikacija i apleta su:
 Java apleti ne mogu da pristupaju datotekama i da pišu ili čitaju
podatke iz njih.
 Java apleti ne mogu da pokreću druge programe na korisničkom
sistemu.
 Java apleti mogu da komuniciraju samo sa serverom sa koga su
učitani.
Java platforma se javlja u tri verzije:
 J2SE - Standard Edition
 J2EE - Enterprise Edition
 J2ME - Micro Edition
Java razvojno okruženje J2SE (Java 2 Standard Edition) obuhvata JRE (Java
Runtime Environment) i JDK (Java Development Kit) (slika 1.4.).

11
Uvod

1
Slika 1.4.

JDK je skup alata sa linijsko komandnim interfejsom za razvoj Java aplikacija


koji uključuje:
 javac - Java Compiler
 rmic - RMI Compiler
 java - Java Interpreter (JVM)
 appletviewer - Pokreće aplete bez upotrebe browser-a
 javadoc - Automatsko generisanje dokumentacije.
JDK nije IDE (Integrated Development Environment). To je sistem sa
komandno linijskim interfejsom bez grafičkog korisničkog interfejsa (GUI).
Java2EE - Enterprise Edition jeste verzija Java platforme koja se fokusira na
rešenja iz oblasti elektronskog poslovanja. Ovu verziju Jave čine sledeće
tehnologije:
 Java Servlets and Java Server Pages.
 Enterprise Java Beans.
 JDBC - Java Database Connectivity
 JavaMail - za slanje i primanje elektronske pošte.
 JAXP - za rad sa XML dokumentima.
 Java Message Service - za asihronu komunikaciju procesa.
J2ME - Micro Edition obezbeđuje fleksibilno i robusno okruženje za aplikacije
koje rade na mobilnim uređajima. To je je platforma za razvoj aplikacija koje su
namenjene za uređaje sa ograničenim hardverskim i memorijskim resursima.
Takvi uređaji su na primer mobilni telefoni, PDA prenosni racunari, kućni

1
izvor: http://docs.oracle.com/javase/7/docs/

12
Uvod

aparati itd. J2ME platforma je na neki način migracija mogućnosti J2SE


platforme na uređaje sa skromnijim mogućnostima procesiranja. Java
platforma za mobilne uređaje na neki način predstavlja podskup J2SE
platforme, sa još nekim dodacima i specifičnostima. Neki zahtevi koji se
postavljaju pred aplikacije za mobilne uređaje i koji zahtevaju dosta sistemskih
resursa nisu mogli biti realizovani na isti način kao što je to u slučaju PC
računara. Zbog toga postoje J2ME biblioteke koje su optimizovane za uređaje
sa ograničenim resursima.
Programski jezik Java ima sintaksu sličnu jezicima C i C++, ali je mnogo strožiji
pri prevođenju, nezavisan je od platforme i ima pojednostavljen sistem
upravljanja memorijom.
Sve Java rezervisane reči su date u tabeli 1.1.

abstract continue for new switch


assert default goto package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while

Tabela 1.1.

Reči kao const i goto su rezervisane, ali se više ne upotrebljavaju. Reči true i
false mogu da se smatraju rezervisanim rečima, mada su one tehnički
boolean literali. Takođe i reč null se može smatrati rezervisanom rečju, ali
tehnički to je null literal.

13
Uvod

14
Klase i objekti

POGLAVLJE 2

2. KLASE I OBJEKTI

Proceduralno programiranje potpuno razdvaja podatke i procese, koji kreiraju,


obrađuju i/ili brišu te podatke. Objektno orijentisana metodologija je uspela da
eliminiše tu razdvojenost.
Objektno orijentisano programiranje, u domenu problema vrši dekompoziciju
(slika 2.1.) i omogućava da se entiteti predstave u prostoru problema. Ove
entitete u prostoru problema i njihovo predstavljanje u prostoru rešanje
nazivamo objektima.

Slika 2.1.

Objektno orijentisano programiranje je zasnovano na ideji da programe treba


organizovati isto kao što su objekti organizovani u stvarnosti. U stvarnom svetu
objekti se sastoje od drugih manjih objekata.
Programer u domenu problema identifikuje entitete, pa se onda entiteti
klasifikuju u klase entiteta. Zatim sledi modelovanje (domen rešenja), odnosno
apstrakcijom se izdvajaju bitne osobine entiteta i klasa entiteta i na taj način se
dolazi do objekata odnosno klase objekata. Nakon toga sledi realizacija,
odnosno pisanje softvera (slika 2.2.).

15
Klase i objekti

Slika 2.2.
Forma i ponašanje objekata definisani su logičkom konstrukcijom koja se
naziva klasa (class).
Objekti su primerci klasa koje predstavljaju osnovne projektne elemente
programa. Pomoću definisane klase može se napraviti proizvoljan broj
objekata. Klase je moguće zamisliti kao šablone ili kalupe, a objekte kao
predmete koje oblikujemo kalupom. Klase su logička apstrakcija, a objekti su
fizička realnost.
Neke od definicija klase su:
 Klasa predstavlja osnovnu organizacionu jedinicu koja omugućava
implementaciju koncepata OOP.
 Klasa predstavlja šablon koji omogućava kreiranje višestrukih
objekata sa sličnim karakteristikama.
 Klase predstavljaju sve karakteristike jednog posebnog niza
objekata odnosno, skup objekata sa istim svojstvima.
 Klasa objekata predstavlja model klase entiteta koji obuhvata
objekte sa istom strukturom i ponašanjem.
Kada se projektuje objektno orijentisani model nekog realnog sistema, ne
definišu se individualni objekti, već klase objekata.
U proceduralnim programskim jezicima postoje ugrađeni tipovi podataka kao
što su int, float, string... Klasa omogućava da se definiše neki novi apstraktni
tip. Kada se definiše ovaj novi tip podataka on može da se koristi za pravljenje
objekata tog tipa. Objekti predstavljaju primerke (instance) klase.
Tako, na primer, ako projektujemo softverski sistem koji treba da predstavi
poslovanje neke firme, onda klasa Zaposleni predstavlja sve zaposlene
radnike te firme, klasa Masine predstavlja sve mašine koje se koriste u
procesu proizvodnje te firme itd.
Skup svih radnika (objekata) sa sličnim osobinama (ime, prezime, datum
rođenja, stručna sprema, stručna usavršavanja, radno mesto...) predstavlja
klasu Zaposleni.
Klase se sastoje od polja, koja definišu svojstva objekata i koja su promenljivi
podaci i metoda koje su skupovi naredbi koje manipulišu poljima i na taj način
menjaju unutrašnje stanje objekata.

16
Klase i objekti

Atributi ili svojstva razlikuju jednu klasu objekata od druge i oni sadrže
informacije o stanju objekata. Svojstva klase Zaposleni predstavljaju na
primer: ime, prezime, radno mesto, plata, norma itd. Atributi definisani unutar
klase nazivaju se promenljive instance, jer svaki objekat klase sadrži svoju
kopiju ovih promenljivih, koje su nezavisne od promenljivih koje sadrže drugi
objekti klase.
Ponašanje ili metode definišu šta i na koji način klasa objekata može da uradi
sebi ili drugim objektima. Ponašanje klase Zaposleni mogu biti na primer:
dođiNaPosao(), opslužiMašinu(), isplatiPlatu(), idiNaPauzu(), ...
Objekti međusobno komuniciraju pomoću metoda, i to tako što jedna klasa
objekata može da pozove metode druge klase objekata da bi promenili neko
svojstvo drugog objekta ili da bi prijavili neku svoju promenu ili da bi zatražili da
drugi objekat uradi nešto.
Na primer, objekat vozačBagera, klase Zaposleni, može da zatraži od objekta
bager, klase Mašine, da pokrene kašiku, ili objekat vozačBagera, klase
Zaposleni, može da obavesti objekat šef, klase Zaposleni, da je posao
završen.

2.1. Deklarisanje klase

Klasa se deklariše korišćenjem ključne reči class, dodelom imena klasi i


navođenjem članova klase unutar vitičastih zagrada:

class Casovnik {

Deklaraciji klase mogu prethoditi modifikatori klasa koji daju određena svojstva
nekoj klasi. Modifikatori mogu biti:
 public, njoj može pristupiti bilo koji Java kod koji može da pristupi
njenom paketu.
 abstarct, klasa se smatra apstraktnom ukoliko je barem jedna metoda
deklarisana kao apstraktna.
 final, ne dozvoljava nasleđivanje, tj. podklase.
Klasa može da sadrži tri vrste članova:
 Polja
• čine strukturu podataka objekta

17
Klase i objekti

• definišu stanje objekta


 Metode
• sadrže izvršni kod
• definišu ponašanje objekta
 Ugnežđene klase i intefejse
Komentari nemaju nikakvu ulogu i zanemaruju se prilikom izvršavanja
programa. Jedina uloga im je da olakšaju preglednost i razumljivost pisanog
koda.
Vrste komentara date su u tabeli 2.1.

Komentar Opis
// Zanemaruju se znakovi do kraja reda.
/* … */ Zanemaruju se svi znakovi između oznaka /* i */.
/** … */ Dokumentacioni komentari.
Tabela 2.1.

Svaki red u izvornom programu koji počinje sa // zanemaruje se prilikom


kompajliranja i izvršavanja programa.
Više redova koji počinju sa /* a završavaju se sa */ zanemaruju se prilikom
kompajliranja i izvršavanja programa.
Redovi koji počinju sa /** a završavaju se sa */ predstavljaju dokumentacione
komentare. Svrha ovih komentara je da opišu deklaracije koje za njima slede.
Primer klase Casovnik sa dodatnim komentarima dat je u nastavku.

Primer 2.1. Casovnik.java

class Casovnik{
// Ovde treba definisati clanove klase
/*
Clanovi klase mogu biti
polja i
metode
*/
}

18
Klase i objekti

2.2. Pravljenje objekata

Deklaracija klase stvara ime tipa. Referenca na objekat datog tipa deklariše se
na sledeći način:

Casovnik mojSat;

Međutim, Deklaracija ne pravi objekat, ona samo deklariše referencu koja se


odnosi na objekat datog tipa. Objekat mora eksplicitno da se napravi.
Objekti se prave pomoću konstrukcionog elementa new.
Tako na primer, nakon deklarisanja reference mojSat klase Casovnik, objekat
je moguće napraviti na sledeći način:

Casovnik mojSat;
mojSat = new Casovnik ();

ili objekat danasnjiDan klase Date moguće je napraviti na sledeći način:

Date danasnjiDatum;
danasnjiDatum = new Date();

Kada se objekat pravi naredbom new navode se tip objekata i svi njegovi
konstrukcioni elementi. Izvršni sistem alocira dovoljno memorije za smeštanje
tog objekata i vraća referencu na dati objekat. Kada objekat prestane da se
koristi izvršni sistem sam uklanja objekat i oslobađa prostor u memoriji koji je
objekat zauzimao.

2.3. Polja

Polja predstavljaju promenljive, i ona definišu stanja klase objekata.


Polje se deklariše tako što se navede ime tipa, zatim sledi ime polja i na kraju,
opciono, klauzula koja daje polju inicijalnu vrednost.

19
Klase i objekti

Deklaraciji polja mogu prethoditi i modifikatori koji kontrolišu određena svojstva


polja. Modifikatori mogu biti modifikatori pristupa, modifikator static i
modifikator final.
Modifikatori pristupa omogućavaju skrivanje podataka (enkapsulaciju) tako
da je tačno definisan način koji omogućava pristup svojstvima nekog objekta.
Detalji implementacije klase su skriveni a korisnik može da menja vrednosti
klasnih promenljivih samo kroz tačno definisan interfejs.
Sva polja i metode jedne klase su uvek dostupni kodu u samoj klasi, ali da bi
se omogućila kontrola pristupa članovima klase od strane drugih klasa koriste
se sledeći modifikatori pristupa:
 Polja deklarisana bez modifikatora pristupa su dostupna samoj
klasi i svim klasama u istom paketu.
 Private; Polja deklarisana kao private dostupna su samo datoj
klasi.
 Public; Polja deklarisana kao public dostupna su svuda gde i
sama klasa.
 Protected; Polja deklarisana kao protected dostupna su samoj
klasi, svim podklasama date klase i svim klasama u istom paketu.

2.3.1. Tipovi podataka

U Java programskom jeziku svaka promenljiva mora da ima svoj tip, svaki
izraz mora da ima svoj tip i svaki tip je strogo definisan. Kod svih dodeljivanja
vrednosti strogo se proverava saglasnost tipova.
Java operiše sa primitivnim tipovima i objektima. Definisano je osam
primitivnih tipova podataka, koji se mogu svrstati u četiri grupe:
 Celi brojevi (integer) – byte, short, int i long;
 Brojevi u pokretnom zarezu (floating point) – float i double;
 Znakovi (character) – char - namenjen simbolima u skupu znakova, na
primer slovima i ciframa;
 Logičke vrednosti – boolean - specijalni tip za predstavljanje vrednosti
tačno/netačno (true/false).
Njihove karakteristike su prikazane u tabeli 2.2.

20
Klase i objekti

Tip Opseg vrednosti Opis

boolean True ili false logički podatak


char 16-bitni Unicode znak
min -128
byte 8-bitni označen ceo broj
max +127
min -32768
short 16-bitni označen ceo broj
max +32767
min -2147483648
int 32-bitni označen ceo broj
max +2147483647
min - 9223372036854775808
long 64-bitni označen ceo broj
max +9223372036854775807
min 3,4 e -038
float 32-bitni brojevi u pokretnom zarezu
max 3,4 e + 038
min 1,7 e –308
double 64-bitni brojevi u pokretnom zarezu
max 1,7 e +308

Tabela 2.2.

Za podatke koji uzimaju logičke vrednosti Java ima boolean tip podataka koji
može da da ima jednu od dve moguće vrednosti: tačno (true) i netačno (false).
Za čuvanje znakovnih vrednosti koristi se podatak tipa char. U Javi se koristi
16-o bitni Unicode standard za prikazivanje znakova.
U Javi je moguće prikazati četiri tipa celobrojnih vrednosti: byte, short, int i
long. Opsezi ovih tipova su prikazani u prethodnoj tabeli.
Brojevi u pokretnom zarezu se koriste za izračunavanje izraza koji daju
vrednosti decimalne tačnosti. Postoje dva tipa brojeva u pokretnom zarezu:
float i double. Float je tip realnog broja sa jednostrukom tačnošću i on se
prikazuje pomoću 32-bitnog broja, a double je realan broj dvostruke tačnosti
koji se predstavlja 64-bitnim brojem.
Konverzija tipova (casting) podrazumeva dodeljivanje vrednosti jednog tipa,
promenljivoj drugog tipa. Na primer, vrednost tipa int može se dodeliti
promenljivoj tipa long.
Konverzija može biti automatska ili izričita (eksplicitna).
Do automatske konverzije tipova će doći samo ukoliko su ispunjena sledeća
dva uslova:
 tipovi su međusobno kompatibilni;
 odredišni tip je veći od polaznog.

21
Klase i objekti

Ukoliko treba vrednosti tipa int dodeliti promenljivoj tipa byte, onda se ova
konverzija neće obaviti automatski, jer je tip byte manji od tipa int. Ova vrsta
konverzije se naziva konverzija skraćivanjem, pošto forsira skraćivanje
promenljive da bi stala u odredišni tip.

Slika 2.3.

Za konverziju međusobno nekompatibilnih tipova mora se upotrebiti izričito


konvertovanje, čiji je opšti oblik sledeći:

(ciljni tip) vrednost

2.3.2. Promenljive

Promenljive služe za čuvanje neke vrednosti.


Pre nego što se upotrebi, promenljiva se mora deklarisati navođenjem njenog
imena i tipa informacije koje će da čuva.
Prvo se navede tip a zatim imena promenljivih odvojenih zarezom i na kraju
sledi znak ";" koji završava svaku naredbu:

int x, y;
Promenljive mogu da imaju i početnu vrednost koja im se dodeljuje prilikom
deklaracije:

float x = 12.6, y = 5.3;

Nema nikakve razlike između promenljivih deklarisanih u jednoj deklaraciji i


onih deklarisanih u više deklaracija istog tipa.
To znači da je:

22
Klase i objekti

int x, y;

isto što i:

int x;
int y;

U Javi postoji tri vrsta promenljivih:


 Lokalne promenljive
 Promenljive instance
 Promenljive klasa
Lokalne promenljive se mogu deklaraisati bilo gde u bloku naredbi, a ne samo
na početku bloka. Svakoj lokalnoj promenljivoj mora se dodeliti vrednost pre
nego što se ona koristi. Lokalna promenljiva prestaje da postoji kada kontrola
toka programa pređe kraj bloka u kome je deklarisana.
Promenljive instance se deklarišu unutar klase i svaki objekat date klase dobija
svoju promenljivu.
Promenljive koje dele svi objekti neke klase nazivaju se klasne promenljive.
Nazivi promenljivih moraju da počnu slovom, donjom crticom (_) ili karakterom
($). Nakon prvog karaktera može da sledi bilo koja kombinacija karaktera ili
cifara.
Java pravi razliku između malih i velikih slova tako da promenljive student i
STUDENT nisu iste.
Da bi programi bili čitljiviji uvode se pravila imenovanja promenljivih. Jedno od
pravila je:
 Prvo slovo u nazivu promenljive je malo
 Svaka sledeća reč počinje velikim slovom bez razmaka
 Ostala slova su mala
Na primer:

int brojPristupa;
String korisničkoIme;
boolean studentJeDiplomirao;

23
Klase i objekti

2.3.3. Izrazi i operatori

Izraz je iskaz koji daje neku vrednost:

int x = 5;
int y = 3;
int z = x*y; // Ovo je izraz
Izrazi se grade korišćenjem operatora. Postoje sledeći operatori:

Operator Operacija Primer


+ Sabiranje 3+5=8
- Oduzimanje 9–7=2
* Množenje 3 * 5 = 15
/ Delenje 15 / 5 = 3
% Modul 17 % 5 = 2
Tabela 2.3.

Za dodavanje i oduzimanje jedinice od promenljive (inkrementiranje i


dekrementiranje) postoje posebni operatori: ++ i --.
Oparatori inkrementiranja i dekrementiranja su prefiksni ako se nalaze ispred
promenljive (--y) i postfiksni ako su smešteni posle promenljive (x++).
Kod korišćenja prefiksne notacije, na primer, y = ++x promenljiva x se prvo
uvećava za jedan, a zatim se x dodeljuje y.
Kod korišćenja postfiksne notacije, na primer, y = x++ promenljivoj y se prvo
dodeljuje vrednost x, a zatim se x uvećava za jedan.
Na primer:

int x, y;
x = 5;
y = x++; // y ima vrednost 5 a x ima vrednost 6
x = --y; // x ima vrednost 4

Za aritmetičke operacije se koristi i skraćen oblik ovih operatora u specifičnim


slučajevima:

Operacija Skraćena operacija


x=x+y x += y

24
Klase i objekti

x=x-y x -= y
x=x*y x *= y
x=x/y x /= y
Tabela 2.4.
Oparatori poređenja su:

Operator Opis
== Jednako
!= Nije jednako
> Veće
< Manje
>= Veće ili jednako
<= Manje ili jednako
Tabela 2.5.

Logički operatori su:

Operator Operacija
! Negacija
& Konjukcija (AND)
| Disjunkcija (OR)
&& Uslovna konjukcija
|| Uslovna disjunkcija
Tabela 2.6.

2.3.4. Pristup poljima

Sada je moguće deklaraciji klase dodati definiciju polja date klase.


Apstrakcijom se definiše da je model časovnika određen poljima: sat, minut,
sekunda i tip. Tip polja može biti neki elementaran tip, što je slučaj za polja sat,
minut i sekunda koji su tipa int, ali tip polja može biti definisan i nekom drugom
klasom, kao što je u primeru Časovnika tip časovnika određen klasom String.

25
Klase i objekti

Primer 2.2. Casovnik.java

class Casovnik {
int sat;
int minut;
int sekunda;
String tip;
}

Polju objekta neke klase pristupa se preko reference na objekat te klase


pomoću operatora(.). Ako, na primar, imamo klasu Casovnik i želimo da
pristupimo poljima sat, minut, sekunda i tip objekta mojSat koji predstavlja
instancu te klase to možemo da uradimo na sledeći način:

Casovnik mojSat ;
mojSat = new Casovnik ();
mojSat.sat= 12;
mojSat.minut= 0;
mojSat.sekunda= 0;
mojSat.tip= “Rolex”;

2.3.5. Statička polja

Ako je potrebno da svi objekti neke klase dele samo jedan primarak polja, ova
polja se deklarišu modifikatorom static. Kada u klasi postoji polje deklarisano
kao static onda postoji samo jedno polje bez obzira koliko je primeraka te
klase napravljeno.
Na primer, klasi Casovnik moguće je dodati još jedno polje serijskiBroj i
definisati statičko polje redniBroj na sledeći naćin:

Primer 2.3. Casovnik.java

class Casovnik {
int sat;
int minut;
int sekunda;
String tip;
int serijskiBroj;
static int redniBroj = 0;
}

26
Klase i objekti

Ako se zatim deklariše i napravi više objekata klase Casovnik:

Casovnik a, b,c;
a = new Casovnik ();
b = new Casovnik ();
c = new Casovnik ();

Sve tri instance klase Casovnik raspolagaće samo sa jednim primerkom polja
redniBroj.
Statičkom polju pristupa se preko imena klase:

a.serijskiBroj = Casovnik.redniBroj ++; // redniBroj = 1

ili preko reference na objekat te klase:

b.serijskiBroj = b.redniBroj ++; // redniBroj = 2


c.serijskiBroj = c.redniBroj ++; // redniBroj = 3

2.3.6. Konstantna polja

Ako, prilikom projektovanja klase želimo da imamo neko konstantno,


nepromenljivo polje onda koristimo modifikator final.
Ako se polje deklariše kao final onda ono mora i da se inicijalizuje i mora da se
zna njegova vrednost u trenutku kreiranja klase a svaki pokušaj promene tog
polja dovodi do greške u vreme kompajliranja programa.
Na primer:

Primer 2.4. Krug.java

class Krug {
public int x1,y1, r;
public final float pi = 3.141592653;
}

27
Klase i objekti

2.4. Metode

Metode klase sadrže kod koji obično menja stanje objekta.


Deklaracija metode se sastoji iz dva dela: zaglavlja i tela.
Zaglavlje mora da sadrži tip rezultata koji vraća metoda i ime metode sa listom
parametra unutar zagrade. Opciono, zaglavlje može da sadrži i skup
modifikatora, koji mogu biti modifikatori pristupa, modifikator abstract, static i
final.
Tip rezultata koji metoda vraća može biti neki primitivni ili apstraktni tip, a ako
metoda ne vraća ništa onda je tip void.
Telo metode sastoji se od skupa naredbi unutar vitičastih zagrada.
Na primer:

Primer 2.5. Casovnik.java

public class Casovnik {


int sati;
int minuti;
int sekunde;
String tip;
int serijskiBroj;
static int redniBroj = 0;
void postaviSerijskiBroj(){
redniBroj++;
serijskiBroj = redniBroj;
}
}

Klasa Casovnik definiše metodu postaviSerijskiBroj(). Metoda


postaviSerijskiBroj() nema argumente i nema povratni rezultat. Ova metoda
uvećava statičku promenljivu redniBroj za jedan i tu vrednost dodeljuje
promenljivoj serijskiBroj.
Metoda se poziva preko reference na objekat uz korišćenje operatora (.).
Ako je data referenca datum na objekat klase Date, tada je tačno vreme
moguće dobiti pozivanjem odgovarajućih metoda klase Data na sledeći način:

28
Klase i objekti

Date datum = new Date();


sati= datum.getHours();
minuti= datum.getMinutes();
sekunde= datum.getSeconds();

Sada je moguće definisati još jednu metodu klase Casovnik, koja će izračunati
tačno vreme i prikazati ga korisniku.

void tacnoVreme(){
Date datum = new Date();
sati= datum.getHours();
minuti= datum.getMinutes();
sekunde= datum.getSeconds();
System.out.println("Sada je: " + sati+
":" + minuti + ":" + sekunde);
}

Klasa Date je deo biblioteke java.util, pa je neophodno pre upotrebe ove klase
eksplicitno izvršiti njen uvoz pomoću naredbe import:

import java.util;

Metoda tacnoVreme() je bez povratnog rezultata (void) i nema argumente.


Ova metoda kreira objekat datum klase Date i pozivanjem metoda getHours(),
getMinutes() i getSeconds() određuje se stanje polja sati, minuti i sekundę
klase Casovnik.
Kada se metoda pozove kontrola toka se prenosi iz pozivajuće metode u
pozvanu metodu. Naredbe te metode se izvršavaju redom, metoda završava
izvršavanje a kontrola toka se vraća pozivajućoj metodi ako je dosegnut kraj
metode ili nakon naredbe return.

Primer 2.6. Casovnik.java

import java.util.*;
public class Casovnik {
int sati;
int minuti;
int sekunde;
String tip;
int serijskiBroj;
static int redniBroj = 0;

29
Klase i objekti

void postaviSerijskiBroj(){
redniBroj++;
serijskiBroj = redniBroj;
}

void tacnoVreme(){
Date datum = new Date();
sati= datum.getHours();
minuti= datum.getMinutes();
sekunde= datum.getSeconds();
System.out.println("Tacno vreme: " + sati+":" +
minuti+":" + sekunde);
}
}

2.4.1. Prosleđivanje argumenata

Argumenti definisani prilikom deklarisanja metode nazivaju se formalni


argumenti. Argumenti, koji se koriste prilikom poziva metode jesu stvarni
argumenti. Prosleđivanje stvarnih argumenata metodi može da se uradi na dva
načina:
 Prosleđivanje po vrednosti
 Prosleđivanje po referenci
Kod prvog načina vrednost stvarnog argumenta se kopira u formalni argument
tako da promene argumenta u metodi ne utiču na promenu upotrebljenog
argumenta prilikom pozivanja metode.
Kod pozivanja po referenci metodi se prosleđuje referenca na argument tako
da sve promene na referenci, koje se dogode u metodi menjaju i vrednost
pozivajućeg argumenta.
U Java programskom jeziku prosti tipovi (int, double, char...) se prosleđuju po
vrednosti a objekti se prosleđuju po referenci.
Primer 2.7. prikazuje i prosleđivanje po vrednosti i prosleđivanje po referenci.
Argumenti x i y su primitivnog tipa i oni se prosleđuju po vrednosti, a argument
p je objekat klase ProsledjivanjeArgumenata, pa će se on proslediti po
referenci.

30
Klase i objekti

Primer 2.7. ProsledjivanjeArgumenata.java

public class ProsledjivanjeArgumenata {


int a = 1;
int b = 2;
void promeni(int x, int y, ProsledjivanjeArgumenata p){
System.out.println("x = " + x + " y = "+y);
x = x*2;
y = y*2;

System.out.println("a = "+p.a + " b = "+p.b);


p.a = 2*p.a;
p.b= 2*p.b;
}
}

Primer

ProsledjivanjeArgumenata pa = new ProsledjivanjeArgumenata();


int x = 5;
int y = 10;
pa.promeni(x, y, pa);
System.out.println ("x i y se pozivaju po vrednosti");
System.out.println("x = "+x+" "+"y = "+y);
System.out.println ("a i b se pozivaju po referenci");
System.out.println("a = "+pa.a+" "+"b = "+pa.b);

Rezultat ovog primera (slika 2.4.) pokazuje da se argumenti x i y, obzirom da


se prosleđuju po vrednosti, neće promeniti posle poziva metode promeni(), za
razliku od objekta pa, čija se polja a i b menjaju posle poziva metode
promeni().

Slika 2.4.

31
Klase i objekti

2.4.2. Apstraktne metode

Apstraktna metoda se opisuje modifikatorom abstract. Takva metoda je


apstraktna metoda odnosno metoda sa definicijom, ali bez realizacije.
Apstraktna metoda može biti napravljena samo unutar apstraktne klase

2.4.3. Metoda main

Aplikacija pisana u Java programskom jeziku se sastoji od većeg broja klasa.


Uvek se mora obezbediti klasa koja pokreće aplikaciju. Ova klasa mora da
sadrži metodu main koju sistem sam locira i prvo nju izvršava.

Primer 2.8. KolikoJeSati.java

class KolikoJeSati {
public static void main(String[] arg){
Casovnik s = new Casovnik();
s.tacnoVreme();
}
}

Metoda main mora da bude javna (public) i statička (static) a povratni rezultat
je void (ne vraća ništa).
Argumenti (arg) u nizu tipa String su programski argumenti i njih, opciono,
upisuje korisnik prilikom pozivanja programa.
Statička metoda može obavljati opšti zadatak za sve objekte klase i ona može
da pristupi samo statičkim poljima i statičkim metodima klase.

2.4.4. Referenca this

Svaka metoda nekog objekta ima specijalnu referencu this na aktuelni objekat
za koji je data metoda pozvana. Ona definiše način da se prosledi referenca na
tekući objekat kao parametar drugim metodima. Referenca this omogućava
upotrebu imena polja klase u metodi u kojoj je definisana lokalna promenljiva

32
Klase i objekti

istog imena. Samo ime promenljive uvek će se odnositi na datu lokalnu


promenljivu, a ime uz referencu this odnosiće se na polje klase:

void dodajIme(String ime){


this.ime = ime;
}

Kako kod statičke metode nema specifičnog objekta nad kojim se radi, to ne
postoji this referenca. Referenca this se može koristiti samo unutar ne-
statičkih metoda.

2.5. Osnovne kontrolne strukture

Osnovne kontrolne strukture su blokovi, selekcije i iteracije.

2.5.1. Blokovi naredbi

Iskazi su u Javi grupisani u blokove. Blok je najednostavnija kontrolna


struktura. On definiše niz operacija koje se obavljaju strogo po redosledu kojim
su napisane. Početak bloka obeležava se otvorenom velikom zagradom ( { ) a
kraj zatvorenom velikom zagradom ( } ). Blokovi se koriste ili da bi se grupisale
promenljive i metode u definiciji klase ili da bi se definisali iskazi.

void testBlokIskaza() {
int x = 10;
{ // Pocetak bloka
int y = x + 10;
...
} // Kraj bloka
// y ovde ne postoji
}

Promenljive definisane unutar bloka su lokalne i one imaju oblast važenja samo
u tom bloku.
U prethodnom primeru promenljiva y je vidljiva samo u bloku u kom je
definisana, dok je promenljiva x globalna i ona je vidljiva u svim blokovima
metode testBlokIskaza().

33
Klase i objekti

2.5.2. Selekcije

U slučaju bloka više naredbi se izvršava jedna za drugom. Kod selekcija


imamo u opštem slučaju N blokova ali se izvršava samo jedan od njih.
Osnovna selekcija jeste If selekcija. Kod If selekcije se izvršava neki blok
naredbi samo ako je ispunjen određen uslov. If selekcija može da se grafički
prikaže na sledeći način:

Slika 2.5.

Sintaksa If selekcije u Java programskom jeziku je:

if (uslov) {
// blok A
} else {
// blok B
}

Na primer:

if (studentJeDiplomirao == true)
System.out.println (“Student je diplomirao ”);
else
System.out.println (“Student nije diplomirao”);

Ako ne želimo drugi deo if selekcija možemo pisati i skraćeno:

34
Klase i objekti

if (studentJeDiplomirao == true) {
System.out.println (“Student je diplomirao ”);
}

Objekti klase Date raspolažu metodom getDay(), koja za dati datum vraća
redni broj dana.
Klasi Casovnik moguće je dodati i promenljivu dan, koja će služiti kao indikator
koji će korisnika obaveštavati koji je dan. Da bi se redni broj dana u nedelji
preslikao u naziv dana koristi se metoda odrediDan(), kojoj se kao argument
prosleđuje redni broj dana, a metoda vraća naziv dana u nedelji.
Preuređena klasa Casovnik sa metodom odrediDan() data je u primeru 2.9.

Primer 2.9. Casovnik.java

import java.util.*;
public class Casovnik {
int sati;
int minuti;
int sekunde;
String tip;
String dan;
int serijskiBroj;
static int redniBroj = 0;

void postaviSerijskiBroj(){
redniBroj++;
serijskiBroj = redniBroj;
}
void tacnoVreme(){
Date datum = new Date();
sati= datum.getHours();
minuti= datum.getMinutes();
sekunde= datum.getSeconds();
dan = odrediDan(datum.getDay());
System.out.println("Tacno vreme: " +
dan + ", " + sati+":"+minuti+":"+sekunde);
}
String odrediDan(int d){
String dan = "Pogresan unos";
if (d == 1){
dan = "pon";
}else if (d == 2){
dan = "uto";
}else if (d == 3){
dan = "sre";
}else if (d == 4){
dan = "cet";
}else if (d == 5){

35
Klase i objekti

dan = "pet";
}else if (d == 6){
dan = "sub";
}else if (d == 7){
dan = "ned";
}
return dan;
}
}

Opšte grananje zasnovano je na selekciji na osnovu vrednosti selektorske


promenljive. Opšti oblik ove selekcije jeste switch selekcija:

switch (selektorskaPromenljiva) {
case vrednost1:
// niz naredbi
break;
case vrednost2:
// niz naredbi
break;
.
.
.
case vrednostn:
// niz naredbi
break;
default:
// niz naredbi
}

Selektorska promenljiva može biti bilo kog tipa od osnovnih tipova byte, char,
short, int. Ona se poredi sa svakom od vrednosti i ukoliko je uslov ispunjen
izvršava se iskaz, a ukoliko se odgovarajuća vrednost ne pronađe izvršava se
default iskaz.
Break prekida izvršenje case selekcije i izvršavanje se nastavlja na prvoj
sledećoj naredbi iza case selekcije.
Metoda odrediDan(), uz upotrebu switch selekcije je prikazana u primeru 2.10.

36
Klase i objekti

Primer 2.10. Metoda odrediDan()

String odrediDan(int d){


String dan;
switch(d){
case 1:
dan = "pon";
break;
case 2:
dan = "uto";
break;
case 3:
dan = "sre";
break;
case 4:
dan = "cet";
break;
case 5:
dan = "pet";
break;
case 6:
dan = "sub";
break;
case 7:
dan = "ned";
break;
default:
dan = "Pogresan unos";
}
return dan;
}

2.5.3. Iteracije

Iteracije su strukture koje imaju za cilj ponavljanje grupe naredbi određen broj
puta.
Iteracije mogu biti:
 Iteracija sa eksplicitnim brojačem (for petlja),
 Iteracija sa izlazom na vrhu (while petlja) i
 Iteracija sa izlazom na dnu (do petlja).

For petlja ponavlja blok naredbi tačan broj puta.

37
Klase i objekti

Opšti oblik naredbe je:

for (inicijalizacija; test; inkrement) {


// blok naredbi;
}

 inicijalizacija je izraz kojim se zadaje početna vrednost brojača petlje,


 test je uslov koji se ispituje nakon svakog koraka petlje,
 inkrement je izraz koji se koristi za menjanje brojača petlje u svakom
koraku petlje.
U primeru KolikoJeSati definiše se for petlja u kojoj se brojač i menja od 0 do
9. U svakoj iteraciji pravi se novi objekat klase Casovnik i dodeljuje se
vrednost "Rolex" ili "Omega" polju tip, u zavisnosti da li je brojač i paran ili
neparan. U nastavku se prikazuje tacno vreme za napravljeni obejkat klase
Casovnik i prikazuje tip casovnika.

Primer 2.11. KolikoJeSati.java

class KolikoJeSati {
public static void main(String[] arg){
for (int i = 0; i < 10; i++){
Casovnik s = new Casovnik();
if (i%2 == 0){
s.tip = "Rolex";
} else{
s.tip = "Omega";
}
s.postaviSerijskiBroj();
System.out.println(s.tip);
s.tacnoVreme();
}
}
}

While petlja se koristi za ponavljanje nekog bloka naredbi sve dok je određen
uslov tačan.
Grafički prikaz ove petlje je:

38
Klase i objekti

blok A uslov

Slika 2.6.
Opšti oblik naredbe je:

while (uslov) {
// blok A
}

Do petlja je slična while petlji samo što se uslov petlje ispituje na kraju petlje.
Grafički prikaz do petlje je prikazan na slici 2.7.

Slika 2.7.
Opšti oblik petlje je:

do {
// blok A
} (uslov)

Kod while petlje moguće je da se telo petlje ne izvrši ni jedanput dok se kod do
petlje telo petlje mora izvršiti barem jedanput.

39
Klase i objekti

2.5.4. Naredbe break i continue u petljama

Naredbom break može se izazvati trenutan prekid rada petlje i izlazak iz petlje
uz preskakanje provere uslova i preostalih naredbi u petlji.
Nakon break naredbe izvršavanje programa se nastavlja na naredbi koja
neposredno sledi iza date petlje.

Na primer:

int i = 0;
while (i < 100) {
i++;
System.out.println (" i = " + i);
if (i == 10)
break;
}

Ova petlja prekida sa radom kada promenljiva i bude jednaka 10.


Naredba continue prenosi izvršenje programa direktno na početak petlje. Ona
preskače ostatak naredbi u petlji koje se nalaze posle nje i vraća izvršenje
programa na početak petlje.
Na primer:

int i = 0;
while (i < 10) {

System.out.print (i);
if (i++ % 2 == 0)
continue;
System.out.println("");

Ova petlja ispisuje u svakom redu po dva broja dok je promenljiva i manja od
10.

40
Klase i objekti

2.6. Konstruktori

Objekat, koji modelujemo softverom, u realnom svetu predstavlja neki složeni


sistem koji ima neka svoja unutrašnja stanja koja treba uspostaviti u trenutku
kreiranja objekta. Inicijalna vrednost polja može se navesti u deklaraciji, ali
ponekad je potrebna netrivijalna operacija za kreiranje početnog stanja
objekata. Mehanizmi koji omogućavaju postavljanje tog početnog stanja
objekta su konstruktori.
Konstruktor se definiše kao operacija za inicijalizaciju objekata. Konstruktor je
metoda koja se poziva u trenutku kreiranja objekta. Konstruktori se koriste za
inicijalizaciju objekata, pozivaju se automatski prilikom kreiranja objekta i ne
mogu se direktno pozvati.
Konstruktori moraju da imaju isto ime kao i klasa koju inicijalizuju, i za razliku
od metoda nemaju povratni tip. Mogu da imaju nula ili više argumenata koji
se unose unutar zagrada, nakon new naredbe i naziva konstruktora.
Ako se konstruktor eksplicitno ne definiše, Java pravi podrazumevani
konstruktor (ImeKlase()) koji nema argumente.
Tako na primer:

Casovnik mojSat = new Casovnik();

pravi novi objekat mojSat klase Casovnik, pozivajući podrazumevani


konstruktor koji nema argumente.
Ako u klasi Casovnik definišemo konstruktor Casovnik(), umesto metode
postaviSerijskiBroj, na sledeći način:

Casovnik(){
redniBroj++;
serijskiBroj = redniBroj;
}

Onda će se prilikom kreiranja objekta klase Casovnik statička promenljiva


redniBroj uvećati za jedan i ta vrednost će se dodeliti promenljivoj
serijskiBroj, jer je to definisano u konstruktoru klase Casovnik, i ta vrednost
se dodeljuje polju redniBroj. Na ovaj način je sprečeno da se promenljivoj
redniBroj pristupi na bilo koji način osim pri kreiranju objekata klase
Casovnik, tako da će se prilikom kreiranja svakog objekta klase Casovnik

41
Klase i objekti

uvećati redniBroj čime je sprečena greška koja može da se dogodi prilikom


generisanja serijskog broja casovnika.
Konstruktor može da ima i nekoliko argumenata kao na primer:

Casovnik(String tip){
this.tip = tip;
redniBroj++;
serijskiBroj = redniBroj;
}

Tako da naredbe:

Casovnik sat1 = new Casovnik(“ROLEX”);


// serijskiBroj je 1
Casovnik sat2 = new Casovnik(“OMEGA”);
// serijskiBroj je 2

kreiraju dva objekta klase Casovnik, na koje ukuzuju refrence sat1 i sat2, pri
čemu se polje tip ovih objekata inicijalizuju na “ROLEX“, i “OMEGA“, a
redniiBroj se uvećava za jedan i dodeljuje tu vrednost polju serijskiBroj
objektima na koje ukazuju reference sat1 i sat2.
Ako se u Java programu definiše konstruktor koji ima jedan ili više argumenta
onda se mora eksplicitno definisati konstruktor bez argumenata. U tom slučaju
Java ne pravi podrazumevani konstruktor.

2.6.1. Preklapanje metoda

U okviru jedne klase više metoda mogu da imaju isto ime ako imaju različit broj
ili tipove argumenata. Ova pojava se naziva preklapanje metoda
(overloaded) jer ime metode ima više od jednog značenja.
Pri pozivu metode, kompajler upoređuje broj i tip argumenata da bi pronašao
odgovarajuću metodu
Preklapanje metode je neophodno kada klasa ima više konstruktora
Kada se iz konstruktora poziva drugi konstruktor, to se može uraditi pomoću
rezervisane reči this, sa odgovarajućom listom argumenata.
Pomoću rezervisane reči this može se pozvati samo jedan konstruktor, i ta
naredba mora biti prva. Konstruktor se može pozvati samo iz drugog
konstruktora, nikako iz neke druge metode.

42
Klase i objekti

Casovnik(String tip){
this();
this.tip = tip;
}

U primeru 2.12. u klasi Casovnik definisana su dva konstruktora. Konstruktor


sa jednim argumentom tipa String i konstruktor bez argumenata.

Primer 2.12. Casovnik.java

import java.util.*;
public class Casovnik {
int sati;
int minuti;
int sekunde;
String tip;
int serijskiBroj;
static int redniBroj = 0;

Casovnik(){
serijskiBroj = ++redniBroj;
}

Casovnik(String tip){
this();
this.tip = tip;
System.out.println("Konstruisan casovnik tipa: " + tip);
}

void tacnoVreme(){
Date datum = new Date();
sati= datum.getHours();
minuti= datum.getMinutes();
sekunde= datum.getSeconds();
System.out.println("Tacno vreme: " + sati+":" +
minuti+":" + sekunde);

}
}

43
Klase i objekti

2.6.2. Inicijalizacija članova klase

Promenljive, elementi klase, koje su primitivnog tipa automatski se inicijalizuju


na nulu, ali reference na objekte se inicijalizuju na vrednost null. Ako se pozove
neka metoda, preko jedne od takvih referenci, kompajler će prijaviti grešku. To
znači da prevodilac ne pravi podrazumevani objekat za svaku referencu, jer to
može da dovede do povećanja režijskih troškova. Da bi se obezbedile inicijalne
vrednosti za svaki objekat neophodno je da se eksplictno izvrši inicijalizacija
Promenljiva, elemenat klase može da se inicijalizuje na dva načina:
 Direktno
 U konstruktoru
Promenljivu ili objekat moguće je inicijalizovati direktno, u trenutku kada se
promenljiva definiše u klasi ili neposredno pre nego što se taj objekat upotrebi.
Korišćenje konstruktora za inicijalizaciju članova daje veću fleksibilnost u
programiranju.

2.6.3. Inicijalizacija statičkih članova

Za statičke članove klase postoji jedinstveno skladište u kome se čuva


vrednost statičkog elementa, bez obzira koliko je objekata napravljeno.
Postavlja se pitanje kada se inicijalizuje to statičko skladište?
Da bi se dobio odgovor na ovo pitanje, pomoći će sledeći primer.
Klasa Soba omogućava kontrolu pravljenja objekata. Klasa Soba na dva
mesta pravi statičke elemente klase Casovnik i jedan nestatičan objekat klase
Casovnik pre statičnog.

Primer 2.13. Soba.java

class Soba{
Casovnik c1 = new Casovnik("Rolex");
static Casovnik c2 = new Casovnik("Rolex - static 1");
Soba(int br){
System.out.println("Konstruktor Soba("+br+")");
c1.info();
c2.info();
c3.info();
}

void info(){
System.out.println("Ovo je soba sa tri

44
Klase i objekti

casovnika");
}

static Casovnik c3 = new Casovnik("Rolex - static 2");


}

U primeru 2.14. prave se dva objekta klase Soba s1 i s2. Rezultat izvršavanja
programa KolikoJeSati prikazan je na slici 2.8.

Primer 2.14. KolikoJeSati.java

class KolikoJeSati {
public static void main(String[] arg){

System.out.println("Prvo konstruisanje objekta Soba");


Soba s1 = new Soba(1);
s1.info();

System.out.println("Drugo konstruisanje objekta Soba");


Soba s2 = new Soba(2);
s2.info();
}
}

Primer pokazuje da se inicijalizacija statičnih elemenata javlja samo ako je


neophodna.

Slika 2.8.

45
Klase i objekti

Ako se ne napravi objekat klase Soba satatički objekti klase Casovnik c2 i c3


nikada neće biti napravljeni.
Na osnovu rezultata programa KolikoJeSati moguće je zaključiti da se statični
elementi inicijalizuju samo kada se pravi prvi objekat klase i nakon toga se više
ne inicijalizuju, kao i da se prvo inicijalizuju statični elementi, a zatim nestatični.

2.6.4. Dealokacija memorije

Java ne poseduje posebnu jezičku konstrukciju kojom se memorija dealocira.


Za dealokaciju memorije zadužen je poseban pozadinski proces programa koji
se naziva garbage collector (sakupljač "smeća").
Sakupljač smeća oslobađa memorijski prostor samo ako je potrebno još
prostora i da bi se izbegla situaciju "out of memory".
Smeće se skuplja bez akcija programera, ali sakupljanje smeća uzima režijsko
vreme, pa zbog toga treba projektovati sisteme koji nisu previše produktivni u
kreiranju objekata.
Sakupljač smeća ne garantuje da će memorija uvek biti raspoloživa za sve
nove objekte, ali omogućava rešavanje problema visećih referenci i curenja
memorije.
Sakupljač smeća radi na principu brojanja referenci. Svaki objekat ima brojač
referenci i uvek kada se objektu pridruži nova referenca, brojač se uveća za
jedan. Kada referenca izađe iz oblasti važnosti, brojač se smanjuje za jedan.
Povremeno sakupljač smeća pretražuje listu objekata i briše objekte za koje su
brojači jednaki nuli.

46
Objektno orijentisano modelovanje

POGLAVLJE 3

3. OBJEKTNO ORIJENTISANO
MODELOVANJE

Modelovanje je osnovni deo aktivnosti koji vodi razvoju dobrog softvera.


Kod razvoja softvera postoje dva glavna načina za modelovanje sistema.
Jedan način je tradicionalni algoritamski a drugi je objektni model.
Algoritamski pristup se zasniva na pitanjima odvijanja aktivnosti i
razlaganja većih algoritama na manje. Kako se menjaju projektni zahtevi
i kako sistem raste, sistem zasnovan na algoritamskoj strukturi se sve
više komplikuje i sve teže održava.
Kod objektnog modelovanja klasa ja osnovna jedinica koja omogućava
realizaciju principa Objektno Orijentisanog Programiranja.
Svaki objekat ima identitet, svojstva i ponašanja. Svaki objekat se
razlikuje od drugog objekta identitetom. Identitet objekta određuje
njegovo ime.
Svaki objekat ima neka svoja unutrašnja stanja koja su opisana njegovim
svojstvima, i svaki objekat može da ima ponašanja kojima mogu da se
menjaju svojstva objekta ili da se utiče na stanja drugih objekata.
Objektno orijentisani pristup se dokazao u projektovanju raznih sistema
različite veličine i kompleksnosti.

3.1. UML

UML (Unified Modeling Language) je objedinjeni jezik za modelovanje,


standardni jezik za objektno orijentisano modelovanje sistema. UML je
standardizovan od strane OMG (Object Management Group) i definiše

47
Objektno orijentisano modelovanje

odgovarajuću vizuelnu sintaksu za opisivanje različitih aspekata


softverske arhitekture. UML se može koristiti za specifikaciju,
vizualizaciju, konstrukciju i dokumentovanje kako softvera tako i
poslovnog procesa.
Konceptualni model UML-a se sastoji od sledećih elemenata:
 osnovni gradivni blokovi (blokovi za izgradnju) UML-a,
 pravila za spajanje tih blokova u celinu i
 opšti mehanizmi.

3.1.1. Gradivni blokovi UML-a

Gradivni blokovi mogu biti:


 Opšta sredstva (stvari)
 relacije i
 dijagrami.

Opšta sredstva mogu biti:


 strukturna,
 sredstva za opis ponašanja,
 sredstva za grupisanje i
 sredstva za označavanje.

Strukturna opšta sredstva su statički delovi modela i to su elementi koji


su ili konceptualni ili fizički.
Strukturna opšta sredstva su:
 Klasa
 Interfejs
 Kolaboracija (društva saradnika)
 Slučaj upotrebe
 Aktivna klasa
 Komponenta
 Čvor

48
Objektno orijentisano modelovanje

Opšta sredstva za opis ponašanja su dinamički delovi UML-a, koji


predstavljaju ponašanje u vremenu i prostoru.
Opšta sredstva za opis ponašanja su:
 Interakcija; dinamički deo UML-a, predstavlja ponašanje koje
uključuje razmenu poruka između objekata da bi se ostvarila
određena svrha. Grafički se predstavlja punom linijom za
zatvorenom punom strelicom na kraju.
 Konačni automat (mašina stanja); definiše sekvencu stanja
kroz koja prolazi objekat u toku svog životnog ciklusa.

Opšta sredstva za grupisanje su organizacioni delovi UML modela.


Postoji samo jedno grupišuće opšte sredstvo i to je paket.
Opšta sredstva za označavanje su delovi sa objašnjenjima u UML
medelu. Opšte sredstvo za označavanje je komentar.
U jeziku UML postoji četiri vrste relacija:
 Zavisnost
 Asocijacija
 Generalizacija
 Realizacija

Dijagram je grafička predstava skupa elemenata, a najčešće je iskazan


kao povezan graf grana (relacija) i čvorova (opšta sredstva). Dijagramom
se sistem prikazije vizuelno iz različitih perspektiva.
U jeziku UML postoje sledeće osnovne vrste dijagrama
 Dijagram klasa; Strukturni dijagram koji predstavlja skup klasa,
interfejsa, društva saradnika i njihove međusobne relacije.
 Dijagram objekata; Strukturni dijagram koji predstavlja skup
objekata i relacije između njih.
 Dijagram slučajeva upotrebe; Dijagrami ponašanja koji
pokazuju korisničke funkcije.
 Dijagram sekvence; Dijagrami ponašanja koji pokazuju neku
interakciju, ističući vremenski poredak.
 Dijagram kolaboracije; Dijagrami ponašanja koji pokazuju neku
interakciju, ističući strukturnu saradnju objekata.

49
Objektno orijentisano modelovanje

 Dijagram stanja; Dijagrami ponašanja koji pokazuju neki


konačni automat, ističući povezanost njegovog ponašanja sa
događajima objekata.
 Dijagram aktivnosti; Dijagrami ponašanja koji pokazuju neki
konačni automat, ističući odvijanje aktivnosti.
 Dijagram komponenata; Strukturni dijagram koji pokazuje skup
komponenti i njihove relacije.
 Dijagram implementacije; Strukturni dijagram koji pokazuje
skup čvorova i relacije između njih.

3.2. Strukturno modelovanje

3.2.1. Klase

Klasa je osnovni projektni elemenat objektno orijentisanog programiranja


i ona služi za modelovanje apstrakcije. Klasa definiše skup objekata sa
istim atributima, operacijama i relacijama.
U UML jeziku klasa se grafički predstavlja pomoću pravouganika koji je
podeljen na tri oblasti koje služe za predstavljanje imena, atributa i
operacija (metoda) klase (slika 3.1.).

Tacka Ime klase


koordinataX
koordinataY Atributi

izbrisi() Operacije

Slika 3.1.

Na ovaj način moguće je vuzuelno predstaviti klasu nezavisno od


programskog jezika. Ime klase obično počinje velikim slovom a svaka
nova reč u imenu takođe počinje velikim slovom. Ime klase mora da
bude jedinstveno. Klasa se može predstaviti i samo pravouganikom sa
imenom klase (slika 3.2.).

50
Objektno orijentisano modelovanje

Tacka Duz Trougao

Slika 3.2.

Atributi se grafički predstavljaju tako što se navode odmah ispod imena


klase.
Atributi se mogu predstaviti samo svojim imenom. Ime atributa počinje
malim slovom a svaka nova reč u imenu počinje velikim slovom.
Uz ime atributa može stajati i njegov tip iza znaka “:”, kao i inicijalna
vrednost iza znaka jednakosti (slika 3.3.).

Student
ime : String
prezime : String
brIndeksa : String
diplomirao : Boolean = false

Slika 3.3.

Ispred imena atributa može da stoji oznaka prava pristupa: “+” za javne
atribute (public),”#” za zaštićene (protected) i “-” za privatne (private)
atribute.
Operacija je implementacija nekog servisa koji može zahtevati svaki
objekat klase. Operacije se grafički navode u odeljku odmah ispod
atributa. Operacije mogu biti prikazane samo svojim imenom (slika 3.4.).

Trougao

izbrisi()
nacrtaj()

Slika 3.4.

Operacije mogu biti specificirane navođenjem njene deklaracije (ime, tip i


podrazumevana vrednost argumenata, povratni tip) (slika 3.5.).

51
Objektno orijentisano modelovanje

Student

polaze(p : Predmet, d : Datum, n : Nastavnik)

Slika 3.5.

3.2.2. Interfejsi

Interfejs je kolekcija operacija koja služi za specificiranje servisa neke


klase. Pomoću interfejsa se može izložiti željeno ponašanje nekog
objekta nezavisno od realizacije.
U UML-u interfejs se grafički prikazuje krugom (slika 3.6.).

Runnable

run()

Slika 3.6.

Ako je za razumevanje modela neophodno prikazati operacije interfejsa,


to se može uraditi korišćenjem klasa u vidu stereotipa gde se u
odgovarajućem odeljku navode operacije samo po imenu ili navođenjem
pune deklaracije (slika 3.7.).

<<Interface>>
Runnable

run() : void

Slika 3.7.

52
Objektno orijentisano modelovanje

3.2.3. Paketi

Svaki veliki sistem ima strukturne nivoe. Da bi se razumeo veliki sistem


potrebno je da se apstrakcije grupišu u veće celine.
Paket je mehanizam opšte namene koji u UML-u služi za grupisanje
elemenata modela u grupe.
Paket se u UML-u grafički prikazuje na sledeći način:

mat
Complex
ComplexArray
DoubleArray
Matrix
Slika 3.8.

Paket se predstavlja u vidu kartice sa jezičkom. Ime paketa se stavlja u


jezičak a sadržaj paketa u karticu.
Paket može da sadrži klase, interfejse, druge pakete..

3.2.4. Relacije

Prilikom modelovanja nekog sistema može se primetiti da ima veoma


malo klasa koje su samostalne. Većina njih međusobno sarađuje na
različite načine.
Kod objektnog modelovanja postoje tri vrste relacija između klasa koje
su posebno važne:
 zavisnost, predstavlja korišćenje odnosa između klasa
 generalizacija, povezuje opštije klase sa specifičnijim
 asocijacija, predstavlja strukturnu relaciju između objekata.
Zavisnost je relacija korišćenja koja označava da promena u
specifikaciji jednog opšteg sredstva može uticati na drugo opšte
sredstvo. Grafički, zavisnost se označava isprekidanom linijom
usmerenom ka opštem sredstvu od koga zavisi drugo opšte sredstvo.
Zavisnost se koristi kada se želi prikazati da jedna klasa (A) koristi
usluge druge klase (B). To može biti odnos klijent-server (klasa A poziva

53
Objektno orijentisano modelovanje

operacije klase B) ili instancijalizacije (klasa A pravi objekat klase B)


(slika 3.9.).

A B

Slika 3.9.

Generalizacija je relacija nasleđivanja između izvedene i nasleđene


klase. Generalizacija znači da podklasa može da se koristi gde god
može da se pojavi nadklasa, ali obratno ne važi.
Generalizacija se grafički označava punom linijom sa velikom
zatvorenom praznom strelicom usmerenom prema nadklasi (slika 3.10.).

Tacka Duz

Trougao

Slika 3.10.

Asocijacija je strukturna relacija koja označava da su objekti jedne


klase strukturno povezani sa objektima druge klase. Asocijacija koja
povezuje dve klase naziva se binarna, a ako povezuje više od dve klase
tada se naziva n-arna asocijacija.
Grafički se asocijacija predstavlja punom linijom koja povezuje dve klase
(slika 3.11.). Asocijacija može imati ime koje opisuje njeno značenje.
Kada klasa učestvuje u asocijaciji ona ima određenu ulogu koju vrši u toj
relaciji. Može se eksplicitno zadati ime uloge koju klasa vrši u asocijaciji.
Jedan primerak asocijacije može da poveže više objekata. Taj broj se
zove višestrukost uloge asocijacije i može se definisati pomoću oznaka
prikazanih u Tebeli 3.1.

54
Objektno orijentisano modelovanje

Oznaka asocijacije Opis


1 tačno jedan
n proizvoljno mnogo
1..n jedan i više
0..1 nula ili jedan
5..9 zadati opseg
Tabela 3.1.

Osoba radi za Kompanij a


1..n 1
zaposl eni poslodavac

Slika 3.11.

Jednostavna asocijacija predstavlja relaciju između ravnopravnih


objekata, što znači da su obe klase konceptualno na istom nivou.
Ponekad je potrebno modelovati relaciju između klasa koje predstavljaju
celinu i klasa koje predstavljaju deo. Ova relacija se zove okupljanje
(agregacija) i predstavlja samo posebnu vrstu asocijacije. Specificira se
modifikovanjem obične asocijacije tako što je kraj uz celinu u obliku
otvorenog romba (slika 3.12.). Agregacija ne uvodi nikakva posebna
ograničenja u pogledu ekskluzivne pripadnosti dela celini niti vezanosti
životnog veka celine i dela.

Slika 3.12.

Ako je posebno definisano pitanje vlasništva objekta-dela i njegovog


životnog veka onda se koristi čvršća vrsta agregacije koja se naziva
kompozicija. Kod kompozicije životni vek objekta-dela zavisi od
životnog veka objekta-celine, što znači da objekat-deo ne može nadživeti
objekat-celinu. Objekat-deo pripada samo jednom objektu-celini za
razliku od agregacije gde objekti-delovi mogu biti deljeni od strane više
objekata-celina.
Kompozicija se predstavlja kao agregacija, samo sa ispunjenim rombom
(slika 3.13.).

55
Objektno orijentisano modelovanje

Slika 3.13.

3.2.5. Dijagrami klasa

U objektnom modelovanju sistema dijagrami klasa su najčešći dijagrami.


Dijagrami klasa služe za modelovanje statičkog prikaza sistema sa
aspekta projektovanja.
Dijagrami klasa sadrže sledeća opšta sredstva
 klase,
 interfejse,
 društva saradnika i
 relacije zavisnosti, generalizacije i asocijacije.
Svaka klasa deluje u društvu saradnika (kolaboracija) sa drugim klasama
i ta međusobna saradnja treba da se predstavi, specificira i
dokumentuje. Za tu svrhu se koriste dijagrami klasa.
Pri izradi dijagrama klasa modeluje se samo deo opštih sredstava i
relacija od kojih se sastoji prikaz datog sistema. Zato bi trebalo da se
svaki dijagram klasa odnosi samo na jedno društvo saradnika.
Za modelovanje društva saradnika potrebno je:
 Identifikovati mehanizam koji se želi modelovati. Mehanizam
predstavlja određenu funkciju ili ponašanje dela sistema koji
želimo da modelujemo.
 Za svaki mehanizam identifikovati klase i interfejse i ostala
društva saradnika koja učestvuju u tom mehanizmu.
 Obraditi sve detalje u tim opštim sredstvima.
 Implementirati atribute i operacije.
Dobro strukturiran dijagram klasa ima sledeće osobine:
 fokusiran je na izlaganje jednog aspekta statičkog prikaza
sistema,

56
Objektno orijentisano modelovanje

 sadrži samo one elemente neophodne za razumevanje tog


aspekta i
 obezbeđuje detalje na svom nivou apstrakcije.
Na primer, na sledećoj slici (slika 3.14.) je dat skup klasa koji je uzet
iz implementacije jednog školskog informacionog sistema.

Skola ima Odsek 1..n


1 1..n clan
1..n
1..n 1..n Predavac
clan predaje 1..n
n 1..n
Student pohadja Predmet n
n n
Nastavnik

Slika 3.14.

Klasa Predavac nasleđuje klasu Nastavnik. Klasa Predavac predstavlja


deo klase Odsek koja predstavlja deo klase Skola. Klasa Student
predstavlja deo klase Skola. Student pohađa predmet koji predaje
predavač.

3.3. Modelovanje ponašanja

Svaki realan sistem koji treba modelovati se sastoji od objekata koji


međusobno interaguju. Ta interakcija se ostvaruje slanjem poruka.
Interakcije se koriste da bi se modelovao dinamički aspekt posmatranog
sistema.
Ako imamo skup objekata i skup veza između njih, onda imamo
kompletan statički model koji prikazuje stanje objekata u datom trenutku.
Pri modelovanju promene stanja objekata, potrebno je primetiti da objekti
šalju poruke drugim objektima. Poruka je specifikacija komunikacije
između objekata. Njom se prenose informacije koje treba da proizvedu
neke akcije kod objekta koji prima poruku.

57
Objektno orijentisano modelovanje

Na osnovu poslatih poruka UML može modelovati nekoliko vrsta akcija.


Te akcije su opisane u tabeli 3.2.

Akcija Gr. prikaz Opis


Poziv (call) Poziva operaciju u objektu
Povratak (return) Vraća vrednost
Slanje (send) Šalje signal objektu
Kreiranje (Create) <<create>> Kreira objekat
<<destroy>>
Uništavanje (Destroy) Uništava objekat

Tabela 3.2.

Interakcija se koristi za modelovanje dinamičkih aspekata sistema preko


dijagrama interakcije koji čine dijagrami sekvenci i dijagrami
saradnje (kolaboracije)

3.3.1. Dijagram slučaja upotrebe

Akter (actor) je koherentni skup uloga koje korisnici sistema imaju kada
su u interakciji sa njim.
Akter se prestavlja sličicom čovečuljka (slika 3.15.).

naziv

Slika 3.15.

Slučaj upotrebe je opis skupa sekvence akcija, uključujući i varijacije tih


akcija, koje sistem izvodi da bi proizveo primetan rezultat.
Slučaj upotrebe se grafički prikazuje elipsom (slika 3.16.).

58
Objektno orijentisano modelovanje

ime

Slika 3.16.
Slučajevi upotrebe daju odgovore na sledeća pitanja:
 Ko će koristiti sistem?
 Šta će korisnici moći da urade sa sistemom?
 Kako će to moći da urade?
 Kako bi sistem radio ako bi korisnik to drugačije radio ili ako bi
imao drugačiji cilj?
 Koji problemi mogu da se jave prilikom rada?
Dijagrami slučajeva upotrebe pokazuju odnos između aktera i slučajeva
upotrebe.
Svaka figurica predstavlja učesnika, pravougaonik predstavlja granice
sistema a elipse prdstavljaju slučajeve upotrebe.
Linije predstavljaju interakcije između učesnika i slučajeva upotrebe.
Iz slučajeva upotebe proizilaze sve specifikacije zahteva. Ovim
specifikacijama se određuju sve interakcije između korisnika i sistema.
Dijagramima slučajeva upotrebe (slika 3.17.) se definiše statički prikaz
funkcionalnosti sistema.
Banka

Izvesti o stanju racuna

Kupac

Uplati depozit

Podigni novac

Slika 3.17.

59
Objektno orijentisano modelovanje

3.3.2. Dijagram sekvence

Dijagrami sekvenci (slika 3.18.) služe da modeluju vremenski redosled poruka.


Dijagram sekvence karakterišu:
 Linija života. To je vertikalna isprekidana linija koja pokazuje da
objekat postoji u nekom vremenskom periodu.
 Fokus upravljanja. On se grafički predstavlja uzanim, dugačkim
pravougaonikom koji pokazuje da u tom intervalu objekat izvodi neku
akciju.

o1:Objekat1 o2:Objekat2 o3:Objekat3 o4: Objekat4

o1:dogadjaj
o2:operacija1()
3:operacija3

o2:operacija4()

Slika 3.18.

3.3.3. Dijagram saradnje

Dijagram saradnje (slika 3.19.) modeluje sistem ističući saradnju objekata koji
interaguju.
Ovaj dijagram se grafički predstavlja kao skup čvorova koji predstavljaju
objekte i skup linija koje ih povezuju i preko kojih idu poruke.

60
Objektno orijentisano modelovanje

1: <<create>>
3: zadajAkcije()
4: <<destroy>>
o1:Objekat1 o2:Objekat2

2: zadajVrednosti()

o3:Objekat

Slika 3.19.
Objektno orijentisano modelovanje

62
Nizovi

POGLAVLJE 4

4. NIZOVI

Prilikom rada sa vrednostima osnovnih tipova, svaka vrednost odgovara


jednom identifikatoru. U slučaju kada se vrši obrada velikog broja vrednosti, za
svaku vrednost treba definisati posebnu promenljivu, a pojedinačno
imenovanje, na primer 1000 promenljivih, je veoma nepraktično. U ovakvim
slučajevima je efikasnije koristiti nizove.
U objektno orijentisanom programiranju objekti se prave po nekom kriterijumu
koji je poznat samo u toku izvršavanja programa. Programer ne može da zna
koliko će objekata biti napravljeno, pa ne može da obezbedi za svaki objekat
imenovanu referencu preko koje će taj objekat biti dostupan. Ovaj problem se
rešava čuvanjem objekata. Najednostavniji način za čuvanje objekta jeste
upotreba nizova.
Niż je struktura podataka, kolekcija vrednosti istog tipa. U Javi niz je objekat
koji definiše imenovani skup promenljivih istog tipa. Svaka promenljiva iz tog
skupa naziva se elemenat niza. Da bi se pristupilo nekom elementu niza koristi
se ime niza i celobrojna promenljiva koja se naziva indeks. Indeks se navodi u
uglastim zagradama nakon imena niza. Sam indeks predstavlja pomeraj datog
elementa niza od početka niza. Prvi elemenat niza ima indeks 0, drugi 1 itd.,
što znači da se stotom elementu niza x, čiji su elementi tipa int pristupa na
sledeći način:

int broj = x[99];

Da bi se kreirao niz u Javi potrebno je uraditi sledeće:


 Deklarisati promenljivu u kojoj će se čuvati niz
 Kreirati novi objekat niza i dodeliti mu deklarisanu promenljivu
 Smestiti podatke u niz.

63
Nizovi

4.1. Promenljiva niza

Niz je objekat, pa promenljiva niza koja predstavlja referencu na objekat niza i


sam niz predstavljaju dva odvojena entiteta. Ovi entiteti se čuvaju u posebnim
memorijskim lokacijama, tako da prilikom deklarisanja promenljive niza nije
obavezno i kreiranje niza. Moguće je prvo napraviti promenljivu niza, a kasnije
upotrebiti tu promenljivu kao referencu na neki konkretan niz.
Deklaracija promenljive u kojoj će se čuvati niz vrši se na sličan način kao i
deklaracija obične promenljive, samo što se deklaraciji niza dodaje par srednjih
zagrada '[' i ']' . Tako na primer, promenljiva niza x, koja predstavlja referencu
na niz čiji su elementi celobrojnog tipa definiše se na sledeći način:

int[] x;

Dakle, ovom deklaracijom definiše se promenljiva x koja će čuvati niz objekata


tipa int. Uglaste zagrade govore da promenljiva x neće čuvati pojedinačnu
vrednost, već niz vrednosti. Sam niz još uvek nije napravljen i njemu nije
dodeljen memorijski prostor.
Promenljivu niza moguće je defonisati i na sledeći način:

int x[];

U ovom slučaju uglaste zagrade se nalaze iza imena promenljive, a ne iza


imena tipa kao u prethodnom slučaju.

4.2. Kreiranje niza

Nakon deklarisanja promenljive koja će čuvati niz, potrebno je kreirati objekat


niza. To se može uraditi pomoću operatora new, kao i za svaki drugi objekat,
na sledeći način:

x = new int[10];

Ovaj izraz kreira niz koji sadrži 10 elemenata koji su tipa int i u promenljivu x
smešta referencu na taj niz (slika 4.1.).

64
Nizovi

Definisanje promenljive niza i kreiranje niza može se uraditi jednim iskazom,


kao na primer:

int[] x = new int[10];

Prvo se navodi tip elemenata niza, zatim slede prazne uglaste zagrade, koje
pokazuju da se radi o nizu elemenata a ne o jednoj promenljivoj. Iza znaka "="
navodi se ključna reč new, koja pravi novi objekat niza čiji su elementi tipa int,
a broj elemenata niza određen je brojem u uglastim zagradama nakon oznake
tipa niza. Navedeni iskaz kreira niz koji ima 10 elemenata. Svi elementi niza se
inicijalizuju na podrazumevanu vrednost, a za numeričke vrednosti to je nula.

Slika 4.1.

4.3. Smeštanje podataka u niz

Elementi niza se referenciraju upotrebom imena promenljive niza i vrednosti


indeksa elementa. Indeks se navodi u uglastim zagradama. Indeks elementa
niza ne mora da bude celobrojni literal, već može da budi i bilo koji izraz čiji
rezultat predstavlja celobrojnu vrednost tipa int.
Podatke možemo da smestimo u prethodno definisani niz na sledeći način:

x[0] = 7;
x[1] = 11;
x[2] = 15;

65
Nizovi

...
x[9] = 21;
Svakom članu niza moguće je pristupiti navođenjem odgovarajućeg indeksa
između uglastih zagrada. Indeksi niza počinju sa 0, tako da niz x ima članove
koji su dostupmi pomoću indeksa od 0 do 9.
Inicijalizacija elemenata niza moguća je i prilikom deklarisanja niza. Ovakva
inicijalizacija se postiže dodavanjem znaka "=" posle deklarisanja promenljive
niza, iza koga sledi lista vrednosti u velikim zagradama.
Na primer:

int n = {1, 5, 7, 2, 9};

Ovim kodom istovremeno se deklariše promenljiva niza n i pravi se niz koji ima
pet članova, uz istovremenu inicijalizaciju ovih elemenata. Elementi niza se
dodeljuju redom, tako da će prvi element niza n[0] imati vrednost 1, drugi
elemenat n[1] vrednost 5 itd.
Inicijalizaciju niza moguće je izvršiti i metodom fill klase Arrays, koja je deo
paketa java.util. Tako na primer, niz x, čiji su elementi tipa int, može se
inicijalizovati na sledeći način:

Arrays.fill(x, 5);

Prvi argument metode fill jeste niz koji se inicajalizuje, a drugi argument jeste
vrednost koja će se dodeliti svim elementima datog niza. Pre upotrebe ove
metode potrebno je na početku izvorne datoteke postaviti iskaz import:

import java.util.Arrays;
Kako je metoda fill statička, nju možemo da uvezemo direktno u izvornu
datoteku, pa onda pri pozivu metode ne mora da stoji ime klase.
Objekat niz u Javi ima svojstvo (polje) length koje pokazuje koliko članova ima
dati niz.
Tako na primer kod:

int brojElemenata;
brojElemenata = x.length;

definiše promenljivu brojElemenata koja određuje koliko elemenata ima niz x.

66
Nizovi

4.4. Obrada elemenata niza

Za obradu svih elemenata niza najpogodnije je koristiti petlju sa eksplicitnim


brojačem – for petlju. Na primer, sledeći program (primer 4.1.) definiše niz x sa
10 elemenata tipa int i inicijalizuje te elemente sa slučajno izabranim
vrednostima u opsegu od 0 do 100, a zatim se u sledećoj for petlji štampaju se
svi elementi niza x.

Primer 4.1. Obrada elemenata niza u for petlji

int[] x = new int[10];


for(int i = 0; i < x.length; i++){
x[i] = (int)(Math.random()*100);
}
for(int i = 0; i < x.length; i++){
System.out.println("x[" + i + "] = " + x[i]);
}

Alternativno, umesto numeričke for petlje, za obradu elemenata niza moguće


je koristiti for-each petlju, koja se koristi za obradu kolekcija (primer 4.2.). U
ovoj petlji, umesto definisanja eksplicitnog brojača, definiše se promenljiva
vred, koja uzima vrednosti pojedinačno svakog elementa niza x, a zatim se
vrši obrada promenljive vred u svakom ciklusu petlje.

Primer 4.2. Obrada elemenata niza u for-each petlji

int[] x = new int[10];


int suma = 0;
float srednjaVrednost;
for(int vred : x){
suma = suma + vred;
}
srednjaVrednost = (float)suma/x.length;
System.out.println("Srednja vrednost niza x je "
+ srednjaVrednost);

Opšti oblik for-each petlje je:

for (var : kolekcija)


izraz

67
Nizovi

Promenljiva var uzima vrednosti elemenata, redom iz kolekcije, a zatim se za


svaku vrednost promenljive var izvršava izraz. Izraz može biti i blok naredbi.
Izraz kolekcija mora biti neki objekat klase koja implementira interfejs Iterable.
Promeljiva ciklusa u for-each petlji, prolazi kroz elemente niza, a ne kroz
vrednosti indeksa. Ako prilikom prolaska kroz niz postoji potreba za
vrednostima indeksa pojedinih elemenata, onda i dalje treba koristiti numeričku
for petlju.

4.5. Operacije sa nizovima

Neke od osnovnih operacija sa nizovima su: kopiranje niza, poređenje nizova,


sortiranje niza, pretraživanje niza...

4.5.1. Kopiranje niza

Kopiranjie svih vrednosti jednog niza u drugi moguće je izvršiti pomoću metode
arraycopy klase System. Sintaksa metode arraycopy je sledeća:

System.arraycopy(niz1, indeks1, niz2, indeks2, brElem);

Prvi argument niz1 predstavlja niz iz koga se elementi kopiraju, drugi argument
je indeks od kog treba početi kopiranje, treći je odredišni niz, četvrti je indeks u
odredišnom nizu od koga treba početi kopiranje i poslednji argument je broj
elemenata koji se kopira.
U sledećem primeru (primer 4.3.) prikazana je upotreba metode arraycopy.

Primer 4.3. KopiranjeNiza.java

import java.util.Arrays;
public class KopiranjeNiza {
public static void main(String[] arg){
int[] x1 = new int[10];
int[] x2 = new int[15];
Arrays.fill(x1, 5);
Arrays.fill(x2, 1);
System.out.println("Niz x1");
stampajNiz(x1);

68
Nizovi

System.out.println("Niz x2");
stampajNiz(x2);

System.arraycopy(x1, 0, x2, 5, 5);

System.out.println("Niz x2 posle kopiranja");


stampajNiz(x2);
}
static void stampajNiz(int[] x){
for(int i = 0; i < x.length; i++)
System.out.println("[Element " + i + "] = "
+ x[i]);
}
}

4.5.2. Poređenje nizova

Dva niza su jednaka ako imaju isti broj elemenata i ako je svaki elemenat
jednog niza jednak odgovarajućem elementu drugog niza.
Klasa Arrays raspolaže metodom equals, koja omogućava upoređivanje dva
niza. Opšti oblik ove metode je:

Arrays.equals(tip[] x, tip[] y);

x i y su nizovi čiji elementi mogu biti tipa int, long, short, char, byte, float ili
double.
U sledećem primeru (primer 4.4.), data su tri niza iste dužine. Prvi i treći niz
inicijalizuju se sa vrednošću 5, a drugi sa 7. Prvo poređenje, kao rezultat daje
false, pošto se nizovi razlikuju, a drugo poređenje daje rezultat true, kako su
nizovi x1 i x3 jednaki.

Primer 4.4. PoredjenjeNzova.java

import java.util.Arrays;
public class PoredjenjeNizova {
public static void main(String[] arg){
int[] x1 = new int[10];
int[] x2 = new int[10];
int[] x3 = new int[10];

69
Nizovi

Arrays.fill(x1, 5);
Arrays.fill(x2, 7);
Arrays.fill(x3, 5);
if(Arrays.equals(x1, x2)){
System.out.println("Nizovi x1 i x2 su jednaki");
} else {
System.out.println("Nizovi x1 i x2 nisu jednaki");
}
if(Arrays.equals(x1, x3)){
System.out.println("Nizovi x1 i x3 su jednaki");
} else {
System.out.println("Nizovi x1 i x3 nisu jednaki");
}
}
}

4.5.3. Sortiranje niza

Klasa Arrays obezbeđuje metodu sort, koja omogućava sortiranje niza


upotrebom QuickSort algoritma sortiranja.
U narednom primeru (primer 4.5.) prikazana je upotreba metode sort u slučaju
sortiranja niza čiji su elementi tipa int, kao i u slučaju kada su elementi tipa
String.

Primer 4.5. SortiranjeNiza.java

import java.util.Arrays;
public class SortiranjeNiza {
public static void main(String[] arg){
int[] x1 = {5,7,1,3,9};
String[] x2 = {"jedan", "dva", "tri", "cetiri", "pet"};

Arrays.sort(x1);
stampajNiz(x1);

Arrays.sort(x2);
stampajNiz(x2);
}

static void stampajNiz(int[] x){


for(int i = 0; i < x.length; i++)
System.out.println("[Element " + i + "] = "
+ x[i]);
}

static void stampajNiz(String[] x){

70
Nizovi

for(int i = 0; i < x.length; i++)


System.out.println("[Element " + i + "] = "
+ x[i]);
}
}

4.5.4. Pretraživanje niza

Klasa Arrays raspolaže metodom binarySearch(), koja omogućava brzo


pretraživanje uređenog niza. Ova metoda ima dva argumenta. Prvi argument
predstavlja neki niz, a drugi element jeste vrednost koja se pretražuje u nizu.
Drugi argument mora biti istog tipa kao što su i elementi niza. Metoda
binarySearch(), ako pronađe vrednost, vraća pozitivnu vrednost koja jednaka
indeksu pronađenog elementa, a ako ne pronađe traženu vrednost vraća
negativnu vrednost n. Vrednos (– n – 1) predstavlja poziciju u nizu na koju
treba da se umetne tražena vrednost da bi niz ostao sortiran.
Upotreba metode binarySearch() prikazana je u primeru 4.6.

Primer 4.6. PretrazivanjeNiza.java

import java.util.*;
public class PretrazivanjeNiza {
public static void main(String args[]) {
// definisanje i inicijalizacija niza x
int x[] = new int[10];
for(int i = 0; i < 10; i++)
x[i] = 3 * i;
// prikaz, sortiranje, prikaz
System.out.print("Originalan niz: ");
stampaj(x);
Arrays.sort(x);
System.out.print("Sortiran niz: ");
stampaj(x);
// popunjavanje od 2 do 5 elementa vrednoscu 1
Arrays.fill(x, 2, 5, 1);
System.out.print("Posle popunjavanja elemenata od 2
do 5: ");
stampaj(x);
// sortiranje i prikaz
Arrays.sort(x);
System.out.print("Sortiran niz: ");
stampaj(x);
// binarySearch pretrazivanje 21
System.out.print("Vrednost 21 je na lokaciji ");

71
Nizovi

int index = Arrays.binarySearch(x, 21);


System.out.println(index);
}
static void stampaj(int x[]) {
for(int i = 0; i < x.length; i++)
System.out.print(x[i] + " ");
System.out.println("");
}
}

72
Nizovi

4.6. Objekat String

U Javi ne postoji ugrađeni tip podataka koji bi omogućavao operacije sa nizom


znakova, ali zato Java biblioteka java.lang sadrži klasu String koja ima tu
namenu. Prilikom kreiranja novog objekta klase String nije potrebno objekat
eksplicitno napraviti. Nije potrebno ni navesti dužinu String objekta tako da se
sa ovim objektima veoma lako radi. Svaki niz znakova naveden pod znacima
navoda predstavlja instancu klase String.
String objekat moguće je napraviti i inicijalizovati u jednoj naredbi kao na
primer:

String ime = "Petar";

Ova naredba deklariše promenljivu ime tipa String i inicijalizuje referencu na


objekat tipa String koji ima vrednost "Petar". Kada se jedanput deklariše
promenljiva tipa String, ona kasnije može da se koristi i za čuvanje reference
na neki drugi znakovni niz. Tako na primer, deklarisana promenljiva ime može
da se iskoristi za čuvanje reference na znakovni niz "Pera":

ime = "Pera";

U promenljivoj ime čuva se refrenca na objekat klase String, a ne sam objekat.


Nakon ponovne operacije dodele vrednosti, preko stare reference zapisuje se
nova referenca na novi znakovni niz (Slika 4.2.).

Slika 4.2.

Objekti klase String su nepromenljivi, što znači da jedanput napravljen objekat


klase String ne može da se proširi ili promeni. To znači da kada se promeni
znakovni niz na koji ukazuje neka referenca, odbacuje se ta referenca i
zamenjuje se novom koja ukazuje na novi znakovni niz.

73
Nizovi

Objekat klase String može da se napravi i predavanjem znakovnog niza kao


argumenta konstruktoru klase String, kao na primer:

String ime = new String("Petar");

Klasa String ima više konstruktora, neki od njih, kao i primeri njihovih
korišćenja prikazani su u tabeli 3.1.

Konstruktor O p is Primer

Pravi objekat klase


String() String s = new String()
String bez znakova

Pravi objekat klase char niz = {'a', 'b', 'c'}


String(char nizznakova[]) String inicijalizovan String s = new
nizom znakova String(niz)

Pravi objekat klase


String s = new
String(String literal) String inicijalizovan
String("abc")
literalom

Pravi objekat klase char niz = {'a', 'b', 'c',


String(char nizznakova[], int String inicijalizovan 'd', 'e', 'f'}
pocetak, int brojZnakova) podnizom znakova od String s = new
početnog indeksa String(niz, 2, 2)

Tabela 3.1.

4.6.1. Spajanje znakovnih nizova

Za objekte klase String može se upotrebiti operator spajanja (+), kao na


primer:

String ime = "Petar";


String prezime = "Petrovic";
String imePrezime = ime + " " + prezime;

Ovaj kod definiše referencu imePrezime na objekat klase String koji ima
vrednost "Petar Petrovic". Operator "+" dovodi do stvaranja novog objekta
klase String, koji je različit od stringova koji se koriste kao operandi ove
operacije. U slučaju da su prilikom upotrebe operatora "+" argumenti različitog
tipa, ali da je makar jedan argument tipa String, tada će svi ostali argumenti
biti konvertovani u String i izvršiće se spajanje znakovnih nizova (primer 4.7.).

74
Nizovi

Primer 4.7. SpajanjeZnakovnihNizova.java

public class SpajanjeZnakovnihNizova {


public static void main(String[] arg){
String s1 = "Sto ";
String s2 = " ljudi, ";
String s3 = "sto cudi.";

// Spajanje tri znakovna niza

String s4 = s1 + s2 + s3;
System.out.println(s4);

// Konvertovanje celog broja u String


int broj = 100;
s4 = broj + s2 +s3;
System.out.println(s4);
}
}

Objekti klase String su nizovi vrednosti tipa char i oni raspolažu metodom
length(), koja vraća broj znakova u znakovnom nizu. Tako na primer, kod:

String ime="Petar";
System.out.println(ime.length());

ispisuje na ekranu vrednost 5.

4.6.2. Poređenje znakovnih nizova

Prilikom poređenja vrednosti promenlivih osnovnih tipova koristi se operator


''=='', međutim, ako želimo da uporedimo dva znakovna niza ne možemo
koristiti taj operator, kao u sledećem kodu:

if (korisnickoIme == ime)
dozvoljenPristup();

Na ovaj način upoređuje se da li promenljive korisnickoIme i ime ukazuju na


isti objekat klase String a ne ispituje se da li znakovni nizovi imaju isti sadržaj.

75
Nizovi

Rezultat ovog poređenja će biti tačan, samo ako obe promenljive ukazuju na
isti objekat.
U sledećem primeru (primer 4.8.), u prvom slučaju promenljive s3 i s4 ukazuju
na posebne objekte klase String koji imaju isti sadržaj, ali kako operator "=="
poredi da li reference ukazuju na isti objekat, a ne da li su sadržaji objekta isti
rezultat poređenja će biti false. U drugom slučaju promenljive s1 i s4 ukazuju
na isti objekat, pa je i rezultat poređenja true.

Primer 4.8. PoredjenjePromenljivih.java

public class PoredjenjePromenljivih {


public static void main(String[] arg){

String s1 = "Sto ljudi";


String s2 = " sto cudi!";
String s3 = "Sto ljudi sto cudi!";
String s4 = s1+s2;
// Prikaz Stringova s3 i s4
System.out.println("String s3 = " + s3);
System.out.println("String s4 = " + s4);
//Poredjenje Promenljivih s3 i s4
if (s3 == s4)
System.out.println("Poredjenje s3 == s4
daje rezultat true");
else
System.out.println("Poredjenje s3 == s4
daje rezultat false");
// Promenljive s1 i s4 sada ukazuju na iste objekte

s1 = s4;
// Prikaz Stringova s3 i s4
System.out.println("String s1 = " + s1);
System.out.println("String s4 = " + s4);
//Poredjenje Promenljivih s1 i s4
if (s1 == s4)
System.out.println("Poredjenje s1 == s4
daje rezultat true");
else
System.out.println("Poredjenje s1 == s4
daje rezultat false");
}
}

Poređenje dva objekta klase String, da bi se videlo da li imaju isti sadržaj,


moguće je izvršiti pomoću metode equals klase String.

if (korisnickoIme.equals(ime))

76
Nizovi

dozvoljenPristup();

Metoda equals daje rezultat true samo u slučaju ako oba niza imaju istu
dužinu i ako je svaki znak jednog znakovnog niza identičan odgovarajućem
znaku drugog znakovnog niza.
U sledećem primeru (primer 4.9.) je prikazan način upotrebe metode equals.

Primer 4.9. PoredjenjeStringova.java

public class PoredjenjeStringova {


public static void main(String[] arg){

String s1 = "Sto ljudi";


String s2 = " sto cudi!";
String s3 = "Sto ljudi sto cudi!";
String s4 = s1+s2;
// Prikaz Stringova s3 i s4
System.out.println("String s3 = " + s3);
System.out.println("String s4 = " + s4);
//Poredjenje Promenljivih s3 i s4
if (s3.equals(s4))
System.out.println("Poredjenje s3.equals(s4)
daje rezultat true");
else
System.out.println("Poredjenje s3.equals(s4)
daje rezultat false");
// String s3 pisemo velikim slovima
s3 = "STO LJUDI STO CUDI!";
// Prikaz Stringova s3 i s4
System.out.println("String s3 = " + s3);
System.out.println("String s4 = " + s4);
//Poredjenje Promenljivih s1 i s4
if (s3.equals(s4))
System.out.println("Poredjenje s3.equals(s4)
daje rezultat true");
else
System.out.println("Poredjenje s3.equals(s4)
daje rezultat false");

if (s3.equalsIgnoreCase(s4))
System.out.println("Poredjenje
s3.equalsIgnoreCase(s4) daje rezultat true");
else
System.out.println("Poredjenje
s3.equalsIgnoreCase(s4) daje rezultat false");
}
}

77
Nizovi

Rezultat ovog programa pokazuje da poziv metode equals za objekat s3 sa


argumentom objekta s4, kao rezultat daje true. Promenom promenljive s3,
koja sada referencira novi znakovni niz ispisan velikim slovima, rezultat poziva
metode equals biće false. Konačno, poređenje objekata s3 i s4 metodom
equalsIgnoreCase daje rezultat true, pošto se ovi stringovi razlikuju samo u
veličini slova.

4.6.3. Pristup elementima znakovnog niza

Do određenog znaka znakovnog niza moguće je doći posredstvom indeksa tipa


int, koji određuje pomeraj elementa u znakovnom nizu u odnosu na početni
znak. U pitanju je isti princip koji važi kod refrenciranja elementa običnog niza,
samo što se ovde ne upotrebljavaju uglaste zagrade nego odgovarajuća
metoda.
Metoda chatrAt(int indeks), klase String, pronalazi i vraća znak koji se nalazi
na poziciji određenoj argumentom metode. Vrednost pozicije indeks mora da
bude u opsegu između 0 i (length() – 1).
Kako se pristupa elementima znakovnog niza prikazano je u sledećem primeru
(primer 4.10.).

Primer 4.10. StringElementi.java

public class StringElementi {


public static void main(String[] arg){
String s = "Ko rano rani, dve srece grabi!!! 12345";
int brojSamoglasnika = 0;
int brojSlova = 0;
int brojBrojeva = 0;
for (int i = 0; i < s.length(); i++){
if(samoglasnik(s.charAt(i)))
brojSamoglasnika++;

if (Character.isLetter(s.charAt(i)))
brojSlova++;

if (Character.isDigit(s.charAt(i)))
brojBrojeva++;
}

System.out.println("Dati tekst sadrzi: \n" +


"samoglasnika: " + brojSamoglasnika + "\n" +
"slova: " + brojSlova + "\n" +
"brojeva: " + brojBrojeva);
}

78
Nizovi

static boolean samoglasnik(char ca){


char c = Character.toUpperCase(ca);
if(c=='A' || c=='E' || c=='O' || c=='U' || c=='I')
return true;
else
return false;
}
}

Na početku, definisan je i inicijalizovan tekstom objekat klase String. Prolazak


kroz znakovni niz definisan je u petlji for. Broj iteracija u for petlji određen je
brojem elemenata u stringu s koji se dobija pozivom metode s.length().
Korišćenjem indeksa i u for petlji pristupa se svakom elementu znakovnog
niza, pomoću metode s.charAt(i). Svaki znak, koji se izdvoji pomoću metode
charAt() ispituje se da li je samoglasnik, slovo ili broj.
Da li je dati znak samoglasnik ispituje se metodom samoglasnik(). U metodi
samoglasnik(), prvo se prosleđeni znak pretvara u veliko slovo metodom
toUpperCase, a onda se u if selekciji ispituje da li je znak samoglasnik i ako
jeste vraća se vrednost true.
Da li je znak slovo može se ispitati metodom isLetter klase Character, a da li
je broj metodom isDigit.
Nakon prebrojavanja elemenata niza, po zadatim kriterijumima, na kraju se
dobijeni rezultati prikazuju metodom println.

4.6.4. Pretraživanje znakovnog niza

Metoda indexOf(String s), traži prvo pojavljivanje znaka ili podniza u datom
znakovnom nizu. Metoda vraća poziciju prvog znaka ili podniza, koji je jednak
stringu s. Ukoliko je potrebno pretraživanje znakovnog niza početi od neke
specificirane pozicije, na primer od pozicije indeksOd, onda se može koristiti
drugi oblik metode, odnosno indexOf(String s, int indeksOd). Ako metoda
indexOf ne pronađe dati znak ili podniz u specificiranom znakovnom nizu, ona
kao rezultat vraća -1. Ista vrednost se dobija i kada se metodi prosledi
pogrešan indeks kao argument.
Primena metode indexOf() prikazana je u sledećem primeru (primer 4.11.).
Na početku je definisan znakovni niz s. Ideja je da se u datom znakovnom
nizu prebroji (brojReci) pojavljivanje zadatog stringa (trazenaRec). Prvo se
pronalazi pozicija (indeks) prvog pojavljivanja zadatog stringa pomoću
naredbe s.indexOf(trazenaRec). Ako u string s postoji niz trazenaRec
izvršava se while petlja u kojoj se promenljiva brojReci uvećava za jedan.
Zatim se pretraživanje nastavlja nakon poslednjeg pronađenog znaka u

79
Nizovi

podnizu, čija je pozicija određena sa (indeks + trazenaRec.length()). Petlja se


izvršava sve dok rezultat pretraživanja ne bude -1. Na kraju, rezultat
prebrojavanja se prikazuje korisniku.

Primer 4.11. PretrazivanjeZnakovnogNiza.java

public class PretrazivanjeZnakovnogNiza {


public static void main(String[] arg){
String s = "Ko rano rani, dve srece grabi!!!";

int brojReci = 0;
String trazenaRec = "ra";
int indeks = s.indexOf(trazenaRec);
while(indeks >= 0){
brojReci++;
indeks = indeks + trazenaRec.length();
indeks = s.indexOf(trazenaRec, indeks);
}

System.out.println("U stringu s: " + s + "\n" +


"Rec '" + trazenaRec +
"' se pojavljuje " + brojReci +
" puta");
}
}

Klasa String ima i metodu lastIndexOf(), koja je veoma slična metodi


indexOf(), stim što ona traži poslednje pojavljivanje specificiranog znaka ili
podniza u datom znakovnom nizu.

4.6.5. Poređenje znakovnih nizova

Klasa String ima metodu compareTo(), koja upoređuje dva objekta tipa String
i određuje da li je jedan znakovni niz veći, manji ili jednak drugom. Ova metoda
upoređuje dva znakovna niza tako što poredi njihove odgovarajuće znakove,
počevši od prvog. Poređenje znakova se svodi na poređenje njihovih Unicode
vrednosti. Jedan znak je veći, manji ili jednak drugom znaku, ako je njegova
Unicode vrednost veća, manja ili jednaka Unicode vrednosti drugog znaka.
Jedan String je veći od drugog ako je prvi znak koji se razlikuje od
odgovarajućeg znaka drugog znakovnog niza veći od odgovarajućeg znaka
drugog niza.
Na primer, neka je :

80
Nizovi

string1.compareTo(string2);

Ako je znakovni niz string1 veći od niza string2, rezultat je veći od nule, ako je
manji rezultat je manji od nule, a ako su nizovi jednaki rezultat poređenja je
nula.
Sledeći primer (slika 4.12.) prikazuje upotrebu metode compareTo().
Na početku se deklariše i inicijalizuje niz nizStringova, zatim se metodom
izbora vrši sortiranje elemenata niza koristeći metodu compareTo(). Zamena
elemenata niza vrši se pomoćnom metodom zamena(), a štampanje
elemenata niza metodom prikazi().

Primer 4.12. SortiranjeStringova.java

public class SortiranjeStringova {


public static void main(String[] arg){
String[] nizStringova = {"abc", "ab", "a",
"abcde", "abcd"};
System.out.println("Originalan niz: ");
prikazi(nizStringova);
// Sortiranje niza metodom izbora
for (int i = 0; i < nizStringova.length; i++ ){
for(int j = i + 1; j < nizStringova.length; j++){
if (nizStringova[i].compareTo(nizStringova[j]) > 0)
zamena(nizStringova, i, j);
}
}
System.out.println("Sortiran niz: ");
prikazi(nizStringova);
}

static void zamena(String[] s, int i, int j){


String temp = s[i];
s[i] = s[j];
s[j] = temp;
}

static void prikazi(String[] s){


for (int i = 0; i < s.length; i++ ){
System.out.println(s[i]);
}
}
}

81
Nizovi

4.6.6. Podniz znakovnog niza

Metoda substring(), klase String služi za izdvajanje podniza iz nekog


znakovnog niza. Ova metoda ima dva oblika. U prvom slučaju metoda ima dva
argumenta, prvi je pozicija prvog znaka u nizu, a drugi označava prvu poziciju
iza poslednjeg znaka u podnizu. Tako na primer, sledeća operacija:

String niz = “Programiranje”;


String podniz = niz.substring(3, 7);

kao rezultat izdvaja podniz “gram” i inicijalizuje promenljivu podniz. Dakle,


prethodna komanda izdvaja iz stringa niz elemente na pozicijama 3,4,5 i 6,
stavra podniz od ovih elemenata i dodeljuje ga promenljivoj podniz.
Drugi oblik metode subdtring() ima samo jedan argumen, koji definiše indeks
početne pozicije, a izdvajanje se vrši od te početne pozicije pa do kraja
znakovnog niza. U ovom slučaju operacija:

String niz = “Programiranje”;


String podniz = niz.substring(3);

kao rezultat daje vrednost “gramiranje” promenljivoj podniz.


Sledeći primer (primer 4.13.) pokazuje način izdvajanja reči iz rečenice,
odnosno znakovnog niza. Suština je u tome da se pronađu pozicije praznih
mesta (indeks1, indeks2) u znakovnom nizu, pomoću metode indexOf(“ ”), a
zatim se metodom substring(indeks1, indeks2) izdvajaju podnizovi između
pozicija praznih mesta.

Primer 4.13. IzdvajanjePodniza.java

public class IzdvajanjePodniza {


public static void main(String[] arg){
String znakovniNiz = "Ko rano rani dve srece grabi!";

String trazenaRec = " ";


int indeks1 = 0;
int indeks2 = znakovniNiz.indexOf(trazenaRec);

while(indeks2 >= 0){


System.out.println(znakovniNiz.substring
(indeks1, indeks2));
indeks1 = indeks2 + 1 ;
indeks2 = znakovniNiz.indexOf(trazenaRec, indeks1);
}

82
Nizovi

System.out.println(znakovniNiz.substring(indeks1));
}
}

Isti rezultat moguće je dobiti upotrebom metode split(). Metoda split ima dva
argumenta. Prvi definiše oblik graničnika, a drugi argument je celobrojna
vrednost koja pokazuje koliko puta se dati graničnik može upotrebiti.
U sledećem primeru (primer 4.14.) je pokazano kako se može upotrebiti
metoda split(). Na početku se definiše znakovni niz koji treba da se rastavi na
elemente, a zatim se poziva metoda split(), čiji prvi argument definiše zarez,
prazno mesto i znak uzvika kao graničnike, a drugi argument je nula, što
kazuje da graničnik može da se upotrebi onoliko puta koliko je to moguće,
odnosno da se ceo znakovni niz razdeli na elemente između kojih može da se
nalazi zarez, prazno mesto ili znak uzvika.

Primer 4.14. IzdvajanjePodniza1

public class IzdvajanjePodniza1 {


public static void main(String[] arg){
String znakovniNiz = "Ko rano rani, dve srece grabi!";

String[] reci = znakovniNiz.split("[, !]", 0);


for (String s: reci)
System.out.println(s);
}
}

4.6.7. Znakovni nizovi promeljive dužine

Objekti tipa String su nepromenljivi. Upotrebu znakovnih nizova promenljive


dužine omogućava klasa StringBuffer, koja enkapsulira objekte klase String.
Kada se formira znakovni niz kao objekat klase StringBuffer, on se odmah
pretvara u objekat klase String.
Promenljiva tipa StringBuffer se deklariše na uobičajen način:

StringBuffer sbNiz;

83
Nizovi

Međutim, za razliku od objekata klase String u ovom slučaju za pravljenje


objekta klase StringBuffer mora da se koristi konstrukcioni elemet new:

sbNiz = new StringBuffer(“Znakovni niz”);

U konstruktoru klase StringBuffer se kao argument tipa String koristi za


inicijalizaciju objekta tipa StringBuffer.
Objekat tipa StringBuffer moguće je kreirati i upotrebom konstruktora kome se
kao argument prosleđuje referenca na objekat tipa String:

String refrencaNiz = “Znakovni niz”;


StringBuffer sbNiz = new StringBuffer(refrencaNiz);

Znakovnom nizu, koji je enkapsuliran u objektu tipa StringBuffer, moguće je


dodati novi znakovni niz metodom append, na sledeći način:

sbNiz.append(“ koji može da se menja”);

Nakon ove komande, referenca sbNiz ukazivaće na objekat sa sadržajem


“Znakovni niz koji može da se menja”.
Metoda append može objektu StringBuffer dodati i podniz od nekog niza, na
sledeći način:

StringBuffer bafer = new StringBuffer(“Dobar”);


String s = “danas”;
bafer.append(s, 0, 3);

Poslednja operacija dodaje objektu bafer znakovni podniz objekta s, koji


počinje pozicijom 0 i ima 3 znaka. Objekat bafer sada enkapsulira znakovni niz
“Dobar dan”. Objektu klase StringBuffer, metodom append, moguće je dodati
direktno i promenljive sledećih tipova: boolean, int, byte, long, short, sloat,
double, char i Object.
Metoda replace klase StringBuffer određeni kontinuirani podniz zamenjuje
specificiranim znakovnim nizom. Na primer, kod:

StringBuffer bafer = new StringBuffer(“Tamo ima pet ljudi!”);


String zamena = “pet”;
int pozicija = bafer.lastIndexOf(zamena);
bafer.replace(pozicija, pozicija + zamena.length(), “mnogo”);

84
Nizovi

zamenjuje podniz “pet” znakovnog niza “Tamo ima pet ljudi!”, koji je
enkapsuliran u objektu bafer klase StringBuffer znakovnim nizom "mnogo".
Metoda replace ima tri argumenta. Prva dva argumenta, tipa int, određuju
poziciju početka podniza i indeks prve sledeće pozicije nakon završetka
podniza koji se menja. Treći argument je tipa String i on definiše znakovni niz
koji će biti umetnut.
Umetanje znakovnog niza u objekat tipa StringBuffer, može da se izvrši
metodom insert(), koja ima dva argumenta. Prvi argument je tipa int i određuje
poziciju u objektu klase StringBuffer, gde će se insertovati objekat klase
String koji predstavlja drugi argument metode insert().
Metode klasa String i StringBuffer, kao i ostalih klasa Javinih biblioteka,
njihovi opisi i specifikacije nalaze se u API dokumentaciji, koja je dostupna na
Internetu (http://docs.oracle.com/javase/1.4.2/docs/api/index.html). Forma
prikaza API dokumentacije se sastoji od tri prozora (Slika 4.3.). Sa leve strane
nalaze se dva prozora u kojima su dati svi paketi, kao i spisak svih klasa.
Klikom na odgovarajuću klasu, prikazuje se API dokumentacija za tu klasu u
desnom, većem okviru.

Slika 4.3.

85
Nizovi

86
Enkapsulacija

POGLAVLJE 5

5. ENKAPSULACIJA

Enkapsulacija se definiše kao skrivanje detalja implementacije objekata od


korisnika objekata. Enkapsulacija omogućava razdvajanje konstantnih stvari od
stvari koje je moguće promeniti.
Veoma bitna karakteristika objektno orijentisanog programiranja jeste
mogućnost ponovne upotrebe napisanog programskog koda. To je posebno
izraženo kod biblioteka. Korisnik treba da bude siguran da neće morati da
ponovo piše kod ako se biblioteka promeni, a sa druge strane, autor biblioteke
treba da ima mogućnost da menja i unapređuje biblioteku, a da pri tome ne
postoji bojazan da će te izmene imati uticaja na kod koji je napisao korisnik
biblioteke.
Objektno orijentisano programiranje, rešava ovaj problem principom
enkapsulacije, odnosno upotrebom modifikatora pristupa koji omogućavaju
autoru biblioteke da definiše koji su elementi dostupni korisniku biblioteke, a
koji nisu.
Komponente se povezuju u jednu jedinstvenu celinu upotrebom paketa, a za
modifikatore pristupa je veoma bitno da li se klase nalaze u istom ili različitim
paketima.

5.1. Paketi

Paket čine srodne klase i interfejsi. Srodne klase i interfejsi se grupišu u pakete
koji se mogu nezavisno distribuirati i kombinovati sa drugim paketima kako bi
formirali aplikacije. Paketi omogućavaju klasama da budu dostupne samo ako
su potrebne i onemogućavaju konflikte koji mogu nastati zbog imenovanja

87
Enkapsulacija

klasa. Garantovanje jednoznačnog imenovanja klasa je i jedan od osnovnih


razloga postojanja paketa. Da bi se obezbedilo jednoznačno imenovanje
paketa preporuka je da se za naziv paketa koristi obrnuti naziv internet domena
kompanije. Na primer, ako je naziv internet domena kompanija.com, onda bi
ime paketa bilo com.kompanija. Ovaj paket može da se dalje deli u potpakete,
na primer com.kompanija.zaposleni.
Standardna Java biblioteka podeljena je na više paketa. Svi paketi su potpaketi
paketa java i javax. Hijerarhija paketa i podpaketa omogućava organizaciju
Java klasa, isto kao što su i podaci na disku organizovani u formi kataloga i
podkataloga.
Klasa String se nalazi u paketu java.lang, pa je njeno puno ime
java.lang.String. Međutim, paket java.lang se implicitno uvozi u svaki Java
program, pa je moguće koristiti ime klase String bez kvalifikacije paketa kome
ona pripada.
Standardni Java paketi, u kojima se čuvaju standardne Java klase, a koji se
načešće koriste prikazani su u sledećoj tabeli:

Paket Namena

Glavne klase programskog jezika kao što su Object,


java.lang Math, String, Thread... Za njihovo korišćenje nije
potreban eksplicitan uvoz ovog paketa.
java.io Klase koje obrađuju ulazno/izlazne operacije

java.awt Klase koje služe za pisanje grafičkog korisničkog


interfejsa.
Klase koje podržavaju GUI komponente klase Swing,
java.swing koje su fleksibilnije i jednostavnije za korišćenje od
klasa iż paketa java.awt.
java.applet Klase koje služe za pisanje apleta
java.math Klase koje definišu matematičke operacije
java.net Klase za pisanje mrežnih aplikacija

java.util Klase koje podržavaju standardne operacije kolekcija,


operacije sa vremenskim i datumskim podacima.
Tabela 5.1.

5.1.1. Definisanje paketa

88
Enkapsulacija

Svaka datoteka čije klase i interfejsi pripadaju nekom paketu, na primer paketu
com.kompanija, deklarišu svoje članstvo tom paketu na sledeći način:

package com.kompanija;

Dakle, pripadnost klase nekom paketu određena je iskazom package, koji


treba smestiti u izvornu datoteku u kojoj se klasa nalazi. Ako se u izvornoj
datoteci ne navede iskaz package, onda će klasa pripadati podrazumevanom
paketu. Ime paketa treba da bude jedinstveno, da bi se sprečili konflikti sa
drugim paketima.
Na primer, pripadnost paketu com.kompanija klase Zaposleni definiše se
iskazom package u datoteci gde je klasa Zaposleni smeštena (primer 5.1.).

Primer 5.1. Zaposleni.java

package com.kompanija;
/**
*
* @author Nenad Jovanovic
*/
public class Zaposleni {
String ime;
String prezime;
int zaposleniID;
static int redniBroj = 0;
public Zaposleni(){
redniBroj++;
zaposleniID = redniBroj;
}
public Zaposleni(String ime, String prezime){
this();
this. ime = ime;
this.prezime = prezime;
}

public void prikazi(){


System.out.println("Ime zaposlenog je: " + ime);
System.out.println("Prezime zaposlenog je: " + prezime);
System.out.println("Identifikacioni broj zaposlenog
je: " + zaposleniID);
}
}

Datoteke u kojima se nalaze klase iz nekog paketa, moraju biti smeštene u


podkatalog koji odgovara punom nazivu paketa. Na primer, sve datoteke iz
paketa com.kompanija moraju da se nalaze u podkatalogu com\kompanija.

89
Enkapsulacija

Klasa Zaposleni treba da se nalazi u katalogu /com/kompanija/ (slika 5.1.).

Slika 5.1.

Klasa ZaposleniPrimer, koja koristi klasu Zaposleni, uvozi paket


com.kompanija iskazom import i na taj način je čini dostupnim (primer 5.2.).

Primer 5.2. ZaposleniPrimer.java

/**
*
* @author Nenad Jovanovic
*/
import com.kompanija.*;
public class ZaposleniPrimer {
public static void main(String[] arg){
Zaposleni radnik = new Zaposleni("Petar", "Petrovic");
radnik.prikazi();
}
}

Treba naglasiti da klasa Zaposleni, konstruktor klase Zaposleni i njene


metode treba da budu deklarisane kao public da bi bile dostupne klasi
ZaposleniPrimer. Klase u paketu mogu imati jedno od dva prava pristupa:
paketsko i javno. Tipovi koji nisu javni imaju paketsku oblast važenja što znači
da su:
 raspoloživi za drugi kod u istom paketu i
 sakriveni izvan paketa, ne vide ih čak ni ugneždeni paketi.
Članovi klase takođe specificiraju pravo pristupa, a podrazumevano pravo
pristupa za neki identifikator je paketsko.
Modifikator public biće objašnjen u nastavku.

90
Enkapsulacija

5.1.2. Kompajliranje paketa

Da bi kompajler uspešno kompajlirao klase u paketu, neophodno je eksplicitno


definisati putanju gde se klase nalaze, a to se može uraditi specifikacijom
vrednosti za promenljivu CLASSPATH.
Definisanje promenljive CLASPATH moguće je uraditi na dva načina. Prvi
način jeste korišćenjem opcije –classpath prilikom pokretanja kompajlera iz
komandne linije. Drugi način jeste definisanje promenljive okruženja
CLASSPATH. Promanljiva okruženja CLASSPATH se u Windows okruženju
podešava pomoću dijaloga Environment Variables, koji se pokreće pomoću
dijaloga System Properties (slika 5.2.).

Slika 5.2.

5.1.3. Uvoz paketa

Klasu iz nekog paketa moguće je upotrebiti navođenjem imena paketa ispred


imena klase. Na primer, klasu Date, paketa java.util moguće je upotrebiti na
lsedeći način:

java.util.Date datum = new java.util.Date();

91
Enkapsulacija

Jednostavnije i uobičajenije je da se paket uveze pomoću iskaza import. To se


može postići ako se na početku programa napiše:

import java.util.*;

Na ovaj način dostupne su sve klase paketa java.util. Moguće je iskaz import
koristiti i za uvoz samo određene klase. Na primer, komanda:

import java.util.Date;

uvozi klasu Data, pa je moguće koristiti klasu Date bez navođenja pune
putanje odnosno na sledeći način:

Date datum = new Date();

Iskaz import omogućava uvoz statičkih polja i metoda, a ne samo klasa. Na


primer, iskazom:
import java.lang.System.*;

omogućeno je koršćenje svih statičkih metoda klase System, bez


kvalifikovanja klase u prefiksu, odnosno:

out.println(”Poruka”);// Umesto System.out.println

5.1.4. Predstavljanje paketa UML-om

Paket se u UML-u grafički prikazuje na sledeći način:

mat
Complex
ComplexArray
DoubleArray
Matrix
Slika 5.3.

92
Enkapsulacija

Paket se predstavlja u vidu kartice sa jezičkom. Ime paketa se stavlja u jezičak


a sadržaj paketa u karticu.
Paket može da sadrži klase, interfejse, druge pakete...
Ako se klase A i B nalaze u dva različita paketa i ako su javne one ipak ne
mogu da pristupe jedna drugoj. Da bi se to omogućilo potrebno je da se uveze
odgovarajući paket. To se grafički predstavlja kao zavisnost (slika 5.4.).

mat podaci
Complex ComplexToken
ComplexArray << import >> DoubleToken
DoubleArray MatrixToken
Matrix
Slika 5.4.

Paket Podaci uvozi paket mat tako da klase paketa mat postaju vidljive
klasama iz paketa podaci, ali obrnuto ne važi.
Samo javni delovi paketa mogu biti izvezeni.

5.2. Modifikatori pristupa

Dostupnost promenljivih i metoda neke klase drugim klasama zavisi od toga da


li je ta klasa javna, da li se te klase nalaze u istom paketu, kao i od modifikatora
pristupa.
U okviru jednog paketa svaka klasa može da pristupi bilo kojoj drugoj klasi, ali
to ne znači da su svi članovi neke klase dostupni drugim klasama u paketu.
Dostupnost članova klase kontroliše se modifikatorima pristupa.
Članovi klase mogu biti deklarisani jednim od sledećih modifikatora pristupa:
 public
 private
 protected
U tabeli 5.2. oređena je dostupnost segmenata Javinog okruženja, na osnovu
definisanih modifikatora pristupa. Modifikator protected biće detaljnije opisan u
poglavlju koje obrađuje nasleđivanje.

93
Enkapsulacija

Modifikator
Dostupnost
pristupa
Prijateljski član Za sve klase u istom paketu

public Svuda gde i sama klasa


private Dostupna su samo datoj klasi
Dostupna su samoj klasi, svim potklasama date
protected
klase i svim klasama u istom paketu

Tabela 5.2.

Na slici 5.5. prikazana je dostupnost između klasa u istom paketu, pa se može


videti da klasa iz istog paketa može da pristupi članovima bez modifikatora,
članovima deklarisanim modifokatorom pristupa public, kao i članovima
deklarisanim modifikatorom protected.

Slika 5.5.

Na slici 5.6. prikazan je slučaj kada klase iz drugih paketa pokušavaju da


pristupe članovima klase koja se nalazi u različitom paketu. Sada postoje veća
ograničenja, pa metode iz klase koja pripada drugom paketu mogu da pristupe
samo članovima klase koji su deklarisani modifikatorom public.

94
Enkapsulacija

Slika 5.6.

Za članove koji nisu deklarisani modifikatorom pristupa ne postoji rezervisana


reč, ali se oni nazivaju prijateljskim (friendly) i oni su dostupni metodama bilo
koje klase iz istog paketa. Kako sve klase definisane u jednoj datoteci moraju
da pripadaju jednom paketu, one su po automatizmu i prijateljske, a za sve
klase prijatelje se kaže da imaju paketski pristup.
Članovi deklarisani modifikatorom public dostupni su metodama bilo koje
klase, a posebno korisnicima biblioteke. Klasa Casovnik ima metodu
tacnoVreme(). Ova metoda izračunava tačno vreme i formatira prikaz tačnog
vremena korisniku, ali činjenica je da su polja sat, minut i sekunda definisani
kao public, pa im je moguće pristupiti i van metode tacnoVreme() i zadati im
proizvoljne vrednosti.
Članovi deklarisani modifikatorom private dostupni su samo metodama iste
klase, dok je pristup drugim klasama uskraćen. Da bi se jasno definisao
korisnički interfejs klase Casovnik, sva polja treba deklarisati modifikatorom
private, a metode modifikatorom public (primer 5.3.).

Primer 5.3. Casovnik.java

import java.util.*;
public class Casovnik {
private int sati;
private int minuti;
private int sekunde;
private int serijskiBroj;
static int redniBroj = 0;

String tip;

Casovnik(){
serijskiBroj = ++redniBroj;
}

95
Enkapsulacija

Casovnik(String tip){
this();
this.tip = tip;
System.out.println("Konstruisan casovnik tipa: "
+ tip);
}

public void info (){


System.out.println("Casovnik je tipa :" + tip +
" i serijskog broja: " + serijskiBroj);
}

public void info (int i){


System.out.println("Casovnik " + i +
". je tipa :" + tip +
" i serijskog broja: " + serijskiBroj);
}

public void tacnoVreme(){


Date datum = new Date();
sati= datum.getHours();
minuti= datum.getMinutes();
sekunde= datum.getSeconds();

System.out.println("Na casovniku tipa: "+tip +


" serijskog broja: " + serijskiBroj +" sada je: " +
sati+":"+minuti+":"+sekunde);
}
}

Modifikatorom private može se ograničiti i pravljenje objekata, odnosno može


se sprečiti neovlašćen pristup konstruktoru neke klase.

Primer 5.4. Kafa.java

class Kafa {
private Kafa(){
System.out.println("Skuvaj kafu");
}
static Kafa kuvajKafu(){
System.out.println("Pazi da ne iskipi!");
return new Kafa();
}
}

96
Enkapsulacija

Primer klase Kafa (primer 5.4.) pokazuje upotrebu modifikatora private kada
se želi ograničiti način pravljenja objekata. Objekat klase Kafa nije moguće
napraviti upotrebom konstruktora, nego se mora upotrebiti metoda
kuvajKafu(), koja će to uraditi, ali na jedan kontrolisani način (primer 5.5.).

Primer 5.5. SkuvajKafu.java

class SkuvajKafu{
public static void main(String[] arg){
//Kafa k1 = new Kafa(); // Ovo ne može
Kafa k2 = Kafa.kuvajKafu();
}
}

Članovi deklarisani modifikatorom protected dostupni su metodama svih klasa


iz istog paketa ili bilo kojoj podklasi.
Modifikatori pristupa definišu skrivanje realizacije. Organizovanje podataka i
metoda unutar klase u kombinaciji sa skrivanjem realizacije naziva se
enkapsulacija. Kao rezultat enkapsulacije dobija se tip sa karakteristikama i
određenim ponašanjima. Enkapsulacijom se uvode određena ograničenja
unutar definisanog tipa da bi se odredilo šta korisnik objekata može da menja a
šta ne, kao i zbog razdvajanja interfejsa i realizacije objekta.
Ako korisnici objekata mogu da upućuju poruke samo javnom interfejsu, tada
projektant klase može da menja sve što nije public, a da klijentski programi
ostanu nepromenjeni.
U UML-u se definiše da ispred imena polja može da stoji oznaka prava
pristupa: “+” za javne atribute (public),”#” za zaštićene (protected) i “-” za
privatne (private) atribute.
Uobičajeno pravilo je da se sva polja u klasi deklarišu kao private, a sve
metode kao public. Vodeći se ovim pravilom klasa Zaposleni bi imala sledeći
oblik:

Primer 5.6. Zaposleni.java

public class Zaposleni{


private String ime;
private String prezime;
private final int zaposleniID;
static int redniBroj = 0;
double koef;

public Zaposleni(){

97
Enkapsulacija

redniBroj++;
zaposleniID = redniBroj;
}
public Zaposleni(String ime, String prezime, double koef){
this();
this. ime = ime;
this.prezime = prezime;
this.koef = koef;
}

public void postaviIme(String ime){


this.ime = ime;
}

public void postaviPrezime(String prezime){


this.prezime = prezime;
}

public void postaviKoef(double koef){


this.koef = koef;
}

public String ime(){


return ime;
}

public String prezime(){


return prezime;
}

public int zaposleniID(){


return zaposleniID;
}

public double koef(){


return koef;
}

public void prikazi(){


System.out.println("Ime zaposlenog je: " + ime);
System.out.println("Prezime zaposlenog je: " + prezime);
System.out.println("Identifikacioni broj zaposlenog je:"
+ zaposleniID);
System.out.println("Vrednost koeficijenta je: " + koef);
}
}

98
Upotreba klasa

POGLAVLJE 6

6. UPOTREBA KLASA

Jedna od najvažnjih karakteristika objektno orijentisanog programiranja jeste


mogućnost korišćenja već napisanog programskog koda. Postojeće klase
mogu da se upotrebe u objektno orijentisanom programiranju na dva načina.
Prvi način je okupljanje, koje nastaje kada nova klasa ima kao člana objekat
već postojeće klase. Drugi način je nasleđivanje, kada se nova klasa pravi kao
tip postojeće klase uz dodavanje nekih specifičnosti.

6.1. Okupljanje

Okupljanje se može realizovati na dva načina:


 Kao agregacija i
 Kao kompozicija.
I agregacija i kompozicija su relacije između klasa koje predstavljaju celinu i
klasa koje predstavljaju deo.
Kod agregacije ne postoji zavisnost životnog veka dela od životnog veka
celine, dok kod kompozicije životni vek objekta-dela zavisi od životnog veka
objekta-celine, što znači da objekat-deo ne može nadživeti objekat-celinu.
Objekat-deo pripada samo jednom objektu-celini.
Kompozicija i agregacija se koriste tako što se referenca na objekat već
postojeće klase stavi u novu klasu. Razlika je u tome da li je to refrenca na već
postojeći objekat ili je taj objekat potrebno napraviti unutar objekta-celine.

99
Upotreba klasa

Kao primer posmata se klasa Automobil koja sadrži dve reference na objekte
klasa Motor. Referenca motor1 ukazuje na objekat koji se pravi u konstruktoru
klase Automobil, pa je u pitanju kompozicija, a referenca motor2 ukazuje na
postojeći objekat klase Motor, koji se prosleđuje kao argument metode, pa se
u ovom slučaju radi o agregaciji.

public class Automobil {


private Motor motor1;
private Motor motor2;
public Automobil(){
motor1 = new Motor();//Kompozicija
}
public void postaviMotor(Motor motor){
motor2 = motor;// Agregacija
}
}

Upotreba kompozicije je prikazana u primeru RacunarskaMreza (primer 6.2.).


Klasa personalnih računara PC (primer 6.1.) ima jedno polje tipa String,
konstruktor i metodu toString(). Svaki objekat ima metodu toString(), koja
omogućava da se dati objekat konvertuje u tip String u slučaju kada je to
potrebno. Definisanje metode toString() u klasi PC predstavlja pojavu koja se
naziva redefinisanje metode. Ova pojava će detaljnije biti opisana u nastavku
ovog poglavlja.

Primer 6.1. PC.java

public class PC {
private String ime;

PC(String ime){
System.out.println("Novi PC - " + ime);
this.ime = ime;
}

public String toString(){


return ime;
}
}

Klasa RacunarskaMreza definiše objekte koji čuvaju dva objekta tipa String,
po jedan objekat prostih tipova int i float i jedan objekat klase PC:

100
Upotreba klasa

Primer 6.2. RacunarskaMreza.java

public class RacunarskaMreza {


private String hub;
private String swic;
int max_broj;
float brzina;
PC racunar1;
PC racunar2;
void ispisi(){
System.out.println("hub = " + hub);
System.out.println("svic = " + swic);
System.out.println("max_broj = " + max_broj);
System.out.println("brzina = " + brzina);
System.out.println("PC = " + racunar1);
System.out.println("PC = " + racunar2 );
}
public static void main(String[] arg){
RacunarskaMreza rm = new RacunarskaMreza();
rm.ispisi();
}
}

Rezultat izvršavanja ovog programa je prikazan na slici 6.1.

Slika 6.1.

Prethodni primer pokazuje da se prosti tipovi, kao članovi klase, direktno


definišu, dok se za složene tipove postavlja referenca. Promenljive prostih
tipova, koje su članovi klase biće automatski inicijalizovane na podrazumevanu
vrednost, na primer, promenljive tipa int biće inicijalizovane vrednošću nula.
Međutim, reference na objekte kao članovi klase inicijalizuju se na vrednost
null. Dakle, prevodilac neće automatski da konstruiše objekat neke klase za
svaku referencu, koja je kao član definisana u novoj klasi nego referenca na

101
Upotreba klasa

objekat mora eksplicitno da se inicijalizuje. Reference na objekat se mogu


inicijalizovati:
 gde se objekat definiše,
 u bloku za inicijalizaciju,
 u konstruktoru klase i
 tamo gde se taj objekat upotrebljava.
Klasa RacunarskaMreza1 pokazuje sva četiri načina inicijalizacije referenci na
objekte (primer 6.3.).

Primer 6.3. RacunarskaMreza1.java

public class RacunarskaMreza1 {


private String swic;
private String hub;
int max_broj ;
double brzina;
// inicijalizacija na mestu definicije
PC racunar1 = new PC("PC1") ;
PC racunar2;

RacunarskaMreza1(){
max_broj = 15;
brzina = 1.4;
//Inicijalizacija u konstruktoru
System.out.println("Inicijalizacija u konstruktoru");
racunar2 = new PC("PC2");
}

// blok za inicijalizaciju
{
System.out.println("Inicijalizacija u bloku
za inicijalizaciju");
swic = new String("SWITCH");
}

void ispisi(){
System.out.println("svic = " + swic);
// Inicijalizacija na mestu upotrebe
System.out.println("Inicijalizacija na mestu upotrebe");
hub = "HUB";
System.out.println("utp = " + hub);
System.out.println("max_broj = " + max_broj);
System.out.println("brzina = " + brzina);
System.out.println("PC = " + racunar1);
System.out.println("PC = " + racunar2);
}
public static void main(String[] arg){
RacunarskaMreza1 rm = new RacunarskaMreza1();

102
Upotreba klasa

rm.ispisi();
}
}

Prvi način je inicijalizacija na mestu definicije objekta. Na ovaj način


inicijalizovana je referenca racunar na objekat tipa PC. Ovaj način označava
da će objekat biti inicijalizovan pre poziva konstruktora. Referenca switch na
objekat klase String inicijalizuje se u bloku za inicijalizaciju. Objekat switch
klase String inicijalizovan je u konstruktoru klase, a referenca utp na objekat
klase String inicijalizuje sa na mestu neposredno pre upotrebe.

Slika 6.2.

Izvršavanje programa RcunarskaMreza1 (slika 6.2.) pokazuje da se prvo


izvršava inicijalizacija na mestu definicije objekta, zatim se, pre inicijalizacije u
konstruktoru izvršava inicijalizacija u bloku za inicijalizaciju. Na kraju se
izvršava inicijalizacija na mestu upotrebe datog objekta.
Relacija kompozicije se u UML-u predstavlja punom linijom, stim što se na
kraju objekta celine nalazi popunjen romboid (slika 6.3.).

Slika 6.3.

103
Upotreba klasa

6.2. Nasleđivanje

Nasleđivanje je jedna od najvažnijih karakteristika objektno orijentisanog


programiranja. Nasleđivanje omogućava da jedna klasa proširi drugu klasu.
Nova klasa se naziva potklasa, a klasa koja se proširuje zove se natklasa ili
superklasa.
Proširivanje klase dovodi do:
 nasleđivanje implementacije i
 nasleđivanje tipa.
Nasleđivanjem implementacije nasleđuju se polja i metode superklase, čime se
ta polja čine dostupnim novoj klasi. Nasleđivanje tipa omogućava da potklasa
postane istog tipa kao i superklasa. Konverzija objekta izvedene klase u
objekat osnovne klase naziva se svođenje naviše (upcasting). Konverzija
objekta izvedene klase u objekat osnovne klase je bezbedna konverzija, iz
prostog razloga što svaki objekat osnovne klase ime sva polja i metode koje
ima i svaki objekat izvedene klase. Moguća je i konverzija objekta osnovne
klase u objekat izvedene klase, koja se zove svođenje naniže (downcasting),
ali ta konverzija je nebezbedna jer može biti neispravna.
Nasleđivanje tipa i nasleđivanje implementacije uvek nastupa istovremeno.
Nasleđivanjem i definisanjem novih ponašanja potklasa postaje specijalizovana
verzija svoje superklase. Dodatna polja i dodatne metode, koji se definišu u
novoj klasi, predstavljaju osnovnu razliku objekata te klase u odnosu na objekte
osnovne klase. Svi novi članovi u potklasi su dodatak na već postojeće članove
superklase. Objekti potklase će imati podobjekat osnovne klase, ali to ne znači
da će sva polja i sve metode superklase biti dostupni izvedenoj klasi. Članovi
koji su dostupni izvedenoj klasi nazivaju se nasleđeni članovi. Ako član
osnovne klase nije dostupan u izvedenoj klasi, onda on nije nasleđen član, ali i
nenasleđeni članovi takođe predstavljaju deo objekta izvedene klase.
Nasleđeni članovi klase dostupni su bez ikakvih ograničenja za sve metode
izvedene klase i oni su istovetni novodefinisanim članovima klase. Nasleđeni
članovi se nalaze u objektima izvedene klase, isto kao i polja i metode koji su
definisani u datoj klasi.
U objektu izvedene klase nalaze se i svi nenasleđeni članovi, ali njihova
dostupnost je definisana modifikatorima pristupa u osnovnoj klasi. Modifikatori
pristupa su:
 public,
 private i
 protected.

104
Upotreba klasa

Koji članovi osnovne klase se nasleđuju u izvedenoj klasi zavisi i od činjenice


da li su osnovna i izvedena klasa članovi istog paketa ili nisu. Ako su
superklasa i potklasa članovi istog paketa, onda potklasa nasleđuje sva polja
deklarisana modifikatorom public ili protected, kao i polja koja nisu
deklarisana modifikatorom pristupa. Polje deklarisano modifikatorom pristupa
private se nenasleđuje. Ako superklasa i potklasa ne pripadaju istom paketu,
onda izvedena klasa nasleđuje sva polja deklarisana modifikatorima pristupa
public i protected, dok se polja koja nisu deklarisana modifikatorom pristupa,
kao i polja deklarisana modifikatorom private ne nasleđuju (slika 6.4.).
Da bi klasa, koja se nalazi u jednom paketu, bila dostupna klasama iz drugog
paketa ona mora da se deklariše modifikatorom public. Klasa koja nije javna
dostupna je samo klasama iz istog paketa. Da bi super klasa bila nasleđena u
podklasu, koja se nalazi u drugom paketu, onda superklasa mora da bude
deklarisana kao public.

Slika 6.4.

Modifikator private je najrestriktivniji i on dozvoljava pristup samo iz date klase.


Modifikator protected sprečava pristup iz klase koja nije deo istog paketa, ali
dozvoljava nasleđivanje, dok modifikator public je najmanje restriktivan jer
dozvoljava pristup i iz klasa koje su deo paketa, kao i iz klasa koje pripadaju
drugim paketima. Izostavljanje modifikatora ograničava pristup na klase koje su
deo istog paketa, ali sprečava nasleđivanje u potklasama koje su deo drugih
paketa.
Metode osnovne klase se nasleđuju isto kao i promenljive, što znači da se
privatne metode ne nasleđuju, javne i zaštićene metode se nasleđuju bez
ograničenja, a metode bez modifikatora pristupa se nasleđuju samo u okviru
istog paketa.
Za razliku od običnih metoda, konstruktori osnovne klase se nikada ne
nasleđuju u izvedenoj klasi.

105
Upotreba klasa

6.2.1. Sintaksa nasleđivanja

Klasa koja nasleđuje neku drugu klasu deklariše se korišćenjem ključne reči
class, dodelom indentifikatora klase, navođenjem ključne reči extends i imena
superklase. Na primer, sledeći kod:

class ImePotklase extends ImeSuperklase {


// Definisanje novih clanova
}

deklariše novu klasu ImePotklase koja proširuje klasu ImeSuperklase. Klasa


ImePotklase nasleđuje polja i metode klase ImeSuperklase, ali može da
definiše i nove članove. Objekte klase ImePotklase možemo da smatramo
objektima tipa ImeSuperklase, stim što tada možemo da koristimo samo
članove koji su definisani u osnovnoj klasi. U UML-u relacija nasleđivanja
grafički se predtsavlja punomlinijom sa trouglom na strani superklase (slika
6.5.).

Slika 6.5.

Objekti klase Zaposleni (primer 5.6.) modeluju zaposlene u jednoj kompaniji


koji primaju plate, kako je definisano metodom izracunajPlatu. Međutim, u
kompaniji se razlikuju zaposleni ranici u proizvodnji, čija plata zavisi od broja
radnih sati i direktori, koji na osnovnu platu dobijaju bonuse. Dakle, potrebno je
napraviti još dve klase, klasu ProizvodniRadnik i klasu Direktor. Obe ove
klase treba da budu kao klasa Zaposleni, ali treba da imaju i svoje
specifičnosti, pa je nasleđivanje logičan izbor. Svaki proizvodni radnike jeste
zaposleni i svaki direktor jeste zaposleni. Ova relacija “jeste” je ključna stvar
kod nasleđivanja.
Klasa Zaposleni (primer 6.4.) ima polja ime, prezime i koef, to su članovi
deklarisani kao private, tako da može da im se pristupi samo preko
odgovarajućih javnih metoda. Time se daje sloboda projektantu klase da

106
Upotreba klasa

promeni detalje implementacije, a da to ne utiče na korisnike ove klase.


Privatna polja je moguće promeniti pomoću odgovarajućih metoda:
postaviIme(), postaviPrezime() i postaviKoef(). Identifikacioni broj
zaposlenog zaposleniID je nepromenljiv i zato je deklarisan modifikatorom
final. Klasa Zaposleni ima i metode izracunajPlatu() i prikazi().

Primer 6.4. Zaposleni.java

public class Zaposleni{


private String ime;
private String prezime;
private double koef;
private final int zaposleniID;
static int redniBroj = 0;

public Zaposleni(){
redniBroj++;
zaposleniID = redniBroj;
}
public Zaposleni(String ime, String prezime, double koef){
this();
this. ime = ime;
this.prezime = prezime;
this.koef = koef;
}

public void postaviIme(String ime){


this.ime = ime;
}

public void postaviPrezime(String prezime){


this.prezime = prezime;
}

public void postaviKoef(double koef){


this.koef = koef;
}

public double izracunajPlatu(double vrednostKoef){


double plata = koef*vrednostKoef;
return plata;
}

public String ime(){


return ime;
}

public String prezime(){


return prezime;
}

107
Upotreba klasa

public int zaposleniID(){


return zaposleniID;
}

public double koef(){


return koef;
}

public void prikazi(){


System.out.println("Ime zaposlenog je: " + ime);
System.out.println("Prezime zaposlenog je: " + prezime);
System.out.println("Identifikacioni broj zaposlenog je:
" + zaposleniID);
System.out.println("Vrednost koeficijenta je: " + koef);
}
}

Nasleđena klasa Direktor (primer 6.5.) ima dva konstruktora za preslikavanje


svoje superklase. Ona nasleđuje metode postaviIme(), postaviPrezime(),
postaviKoef(), ime(), prezime(), zaposleniID() i koef(), koje omogućavaju
pristup privatnim nenasleđenim poljima klase Zaposleni. Klasa Direktor
nasleđuje i metodu prikazi(), a definiše nove metode postaviBonus() i
bonus(), koje pristupaju privatnom polju bonus. Objekti klase Zaposleni i klase
Direktor, pored odnosa direktor je zaposen, imaju i različita ponašanja. Ta
različitost se ogleda u različitom načinu izračunavanja zarade. Plata direktora
se izračunava na isti način kao plata zaposlenog, ali sa dodatkom bonusa. To
znači da klasa Direktor ne može da nasledi metodu izracunajPlatu(), već
treba da je ponovo definiše. Obe metode imaju isto ime, isti broj i tipove
argumenata, ali se razlikuju po funkcionalnosti. Pojava kada potklasa definiše
metodu koja ima isto ime i isti broj i tipove argumenata i isti povratni tip kao i
nadklasa naziva se redefinisanje metode. Prema tome, metoda
izracunajPlatu() se u klasi Direktor redefiniše. Da bi se naznačilo da se u
redefinisanoj metodi poziva metoda izracunajPlatu() klase Zaposleni koristi
se ključna reč super. Reč super ne predstavlja referencu ni na koji objekat,
već je to ključna reč koja usmerava kompajler da pozove neku metodu
superklase. Ključna reč super koristi se i pri pozivu konstruktora superklase. U
ovom slučaju se reč super koristi kao ime metode uz navođenje argumenata
konstruktora. Ključna reč super može da se koristi samo u nestatičkim
metodama.

Primer 6.5. Direktor.java

public class Direktor extends Zaposleni {


private double bonus;
public Direktor(){
super();
}

108
Upotreba klasa

public Direktor(String ime, String prezime, double koef,


double bonus){
super(ime, prezime, koef);
this.bonus = bonus;
}

public void postaviBonus(double bonus){


this.bonus = bonus;
}

public double bonus(){


return bonus;
}

public double izracunajPlatu(double vrednostKoef){


double plata = super.izracunajPlatu(vrednostKoef) +
bonus;
return plata;
}
}

Ako potklasa ima metodu koja ima isto ime, ali se razlikuje po povratnom tipu ili
po broju ili tipu argumenata, kao i metoda superklase, onda se ova pojava
naziva preklapanje metode.
Slično, i klasa ProizvodniRadnik (primer 6.6.) nasleđuje sve javne članove
klase Zaposleni, definiše privatno polje brCasova i metode za pristup tom
privatnom polju. I klasa ProizvodniRadnik definiše svoju posebnost u odnosu
na klasu Zaposleni, a ona se ogleda u drugačijem načinu izračunavanja plate.
Ta posebnost se ispoljava u smislu uključivanja broja radnih sati, kao faktora
koji utiče na platu proizvodnog radnika. U ovom slučaju se prvo izračunava
vrednost jednog radnog sata, kao odnos plate zaposlenog i prosečnog broja
radnih sati 174, pa se onda plata proizvodnog radnika dobija kao proizvod
broja radnih sati i vrednosti jednog radnog sata.

Primer 6.6. ProizvodniRadnik.java

public class ProizvodniRadnik extends Zaposleni{


private int brCasova;
public ProizvodniRadnik(){
super();
}

public ProizvodniRadnik(String ime, String prezime,


double koef, int brCasova){
super(ime, prezime, koef);
this.brCasova = brCasova;
}

109
Upotreba klasa

public void postaviBrCasova(int brCasova){


this.brCasova = brCasova;
}

public double brCasova(){


return brCasova;
}

public double izracunajPlatu(double vrednostKoef){


double plata =
(super.izracunajPlatu(vrednostKoef) /174)*brCasova;
return plata;
}
}

Upotreba klase Zaposleni i nasleđenih klasa Direktor i ProizvodniRadnik


prikazana je u primeru ZaposleniPrimer (primer 6.7.). Objekat pr klase
ProizvodniRadnik pravi se upotrebom konstruktora bez argumenta, koji
postavlja vrednost za polje zaposleniID. Upotrebom nasleđenih metoda
postaviIme(), postaviPrezime() i postaviKoef(), definišu se vrednosti
nenasleđenih polja ime, prezime i koef. Privatno polje brCasova, klase
ProizvodniRadnik postavlja se javnom metodom postaviBrCasova(). Plata
proizvodnog radnika se izračunava pozivom redefinisane metode
izracunajPlatu().

Primer 6.7. ZaposleniPrimer.java

import java.text.*;
public class ZaposleniPrimer {
public static void main(String[] arg){

DecimalFormat df = new DecimalFormat("#.##");

ProizvodniRadnik pr = new ProizvodniRadnik();


pr.postaviIme("Petar");
pr.postaviPrezime("Petrovic");
pr.postaviKoef(11.5);
pr.postaviBrCasova(220);
pr.prikazi();
System.out.println("Plata proizvodnog radnika je: " +
df.format(pr.izracunajPlatu(1153.56)));

Direktor d = new Direktor("Laza", "Lazic",


21.22, 50000);
System.out.println("Ime i prezime direktora je: " +
d.ime() + " " + d.prezime());
System.out.println("Bonus direktora je: " + d.bonus());
System.out.println("Plata direktora je: " +

110
Upotreba klasa

df.format(d.izracunajPlatu(1153.56)));
}
}

Objekat d klase Direktor pravi se konstruktorom kome se kao argumenti


prosleđuju ime, prezime, koeficijent i bonus. Nenasleđena polja ime i prezime,
objekta d prikazuju se pozivom nasleđenih, javnih metoda ime() i prezime().
Privatnom polju bonus objekta d pristupa se posredstvom javne metode
bonus() klase Direktor. Plata direktora izračunava se, ponovo redefinisanom
metodom izracunajPlatu().
Polja u nasleđenoj klasi ne mogu da se redefinišu, ona mogu samo da se
sakriju. Ako se u nasleđenoj klasi definiše polje koje ima isto ime kao i neko
polje u superklasi, onda polje superklase i dalje postoji ali ne može da mu se
pristupi direktno preko imena, već mora da se koristi reč super.
Kada se pristupa nekom članu klase koji je ponovo definisan u potklasi, onda
kom elementu se pristupa zavisi od vrste člana, njegove pristupačnosti i načina
referenciranja. Kada se poziva neka metoda preko reference na objekat , onda
tip objekta određuje koja će se implementacija koristiti. Kada se poziva polje
nekog objekta, onda od tipa reference zavisi koje polje će se pozvati.

6.2.2. Konstruktori i nasleđivanje

Nasleđivanjem se ne kopira samo interfejs osnovne klase, već objekat


izvedene klase sadrži podobjekat superklase. Taj podobjekat je neophodno da
bude propisno inicijalizovan, a to može da uradi samo konstruktor superklase.
Inicijalizacija podobjekta se obavlja u konstruktoru izvedene klase ali
pozivanjem konstruktora superklase. Ako se konstruktor superklase ne pozove
eksplicitno, Java automatski poziva konstruktor superklase u konstruktoru
izvedene klase.
Poziv konstruktora osnovne klase mora da bude prva naredba u konstruktoru
izvedene klase. Ako prvi iskaz u konstruktoru izvedene klase nije poziv
konstruktoru superklase, kompajler će sam da umetne poziv podrazumevanog
konstruktora osnovne klase. Ovako ponašanje kompajlera može da dovede do
greške. Poznato je da, ako se u klasi definiše bilo koji konstruktor,
podrazumevani konstruktor neće biti kreiran od strane kompajlera, pa ga je
potrebno eksplicitno napraviti. Ako je u superklasi definisan konstruktor sa
argumentima, a nije i podrazumevani konstruktor, onda će prilikom
automatskog poziva podrazumevanog konstruktora u konstruktoru izvedene
klase doći do greške.

111
Upotreba klasa

U sledećem primeru definisane su klase Jedan, klasa Dva koja nasleđuje


klasu Jedan i klasa Tri koja nasleđuje klasu Dva. U konstruktorima klasa Dva i
Tri nema eksplicitnog pozivanja konstruktora superklase.

Primer 6.8. Dva.java

class Tri extends Dva{


Tri(){
System.out.println("Konstruktor klase TRI");
}

public static void main(String[] arg){


Tri t = new Tri();
}
}

class Dva extends Jedan{


Dva(){
System.out.println("Konstruktor klase DVA");
}
}

class Jedan{
Jedan(){
System.out.println("Konstruktor klase JEDAN");
}
}

Međutim, rezultat izvršavanja programa (slika 6.6.) pokazuje da se konstrukcija


obavlja od osnovne ka izvedenoj klasi.

Slika 6.6.
Posle alokacije memorije za objekat, koji je napravljen, i postavljanja polja na
podrazumevane vrednosti izvršava s se konstruktor. Svaki konstruktor ima tri
faze:
1. Prvo se poziva eksplicitno ili implicitno konstruktor superklase.
Konstruktor superklase, takođe, ima iste tri faze.

112
Upotreba klasa

2. Zatim se inicijalizuju polja, redosledom kojim su deklarisana, kao i


blokovi za inicijalizaciju.
3. Na kraju se izvršava telo konstruktora.

Sledeći primer prikazuje različita stanja konstrukcije:

Primer 6.9. RedosledZavisnostiKonstruktora.java

class RedosledZavisnostiKonstruktora {
public static void main(String[] arg){
KlasaDva d = new KlasaDva();
}
}

class KlasaDva extends KlasaJedan{


int dva = 2;
KlasaDva(){
broj = m(dva);
System.out.println("[KlasaDva] jedan = " +jedan);
System.out.println("[KlasaDva] dva = " +dva);
System.out.println("[KlasaDva] broj/dva = " +broj);
}
}

class KlasaJedan{
int jedan = 1;
int broj;
KlasaJedan(){
broj = m(jedan);
System.out.println("[KlasaJedan] jedan = " +jedan);
System.out.println("[KlasaJedan] broj/jedan = " +broj);
}

public int m(int i){


return (i + broj);
}
}

Rezultat izvršavanja ovog programa je prikazan na slici 6.7..

113
Upotreba klasa

Slika 6.7.

U tabeli 6.1. prikazane su vrednosti polja, u različitim fazama izvršavanja


konstruktora, pri konstruisanju objekta klase KlasaDva. U prvom koraku polja
se postavljaju na podrazumevane vrednosti. Kako su polja tipa int,
podrazumevane vrednosti će biti 0. Zatim se poziva konstruktor klase
KlasaDva. Prilikom kreiranja objekta klase KlasaDva, poziva se implicitno
konstruktor super klase, odnosno KlasaJedan(). Pošto je svaki objekat
nasleđen od stane klase Object, u trećem koraku biće pozvan i konstruktor
Object(). U četvrtom koraku, pošto su pozvani svi konstruktori superklasa, vrši
se inicijalizacija polja klase KlasaJedan i promenljivoj jedan zadaje se vrednos
1. Posle inicijalizacije polja klase KlasaJedan izvršava se telo konstruktora
klase KlasaJedan, pa se promenljivoj broj dodeljuje vrednost 1. Nakon toga,
izvršava se inicijalizacija klase KlasaDva, posle čega je vrednost promenljive
dva postavljena na 2. I u zadnjem koraku se izvršava telo konstruktora
KlasaDva(), odnosno poziva se metoda m(2), koja vraća vrednost 3, koja se
dodeljuje promenljivoj broj. Vidimo da su vrednosti promenljivih jedan, dva i
broj posle poslednjeg koraka u skladu sa vrednostima koje se dobija
izvršavanjem programa.

Dešavanja jedan dva broj

0 Polja se postavljaju na podrazumevane 0 0 0


vrednosti

1 Poziva se konstruktor dva() 0 0 0

2 Poziva se konstruktor jedan() 0 0 0

3 Poziva se konstruktor Object() 0 0 0

4 Inicijalizacija polja klase Jedan 1 0 0

5 Izvršavanje konstruktora Jedan() 1 0 1

6 Inicijalizacija polja klase Dva 1 2 1

7 Izvršavanje konstruktora Dva() 1 2 3

Tabela 6.1.

114
Upotreba klasa

6.2.3. Modifikator protected

Pravilo dobrog projektovanja klase je da bi sva polja klase trebalo da budu


deklarisana modifikatorom pristupa private, dok metode treba deklarisati
modifikatorom pristupa public. Svi članovi deklarisani kao private nisu vidljivi
udrugim klasama, kao ni u potklasama. Nekada je potrebno metodu, a ređe i
polje učiniti dostupnim samo potklasi. Tada se član klase deklariše
modifikatorom pristupa protected.
Deklarisanje polja kao protected može da dovede do situacije da korisnici date
klase mogu da naslede datu klasu, a zatim da pristupaju direktno zaštićenim
poljima. To je u suprotnosti sa principom enkapsulacije objektno orijentisanog
programiranja jer se autoru klase onemogućava promena implementacije
klase.
Upotreba metoda deklarisanih kao protected ima više smisla. Zaštićenu
metodu nasleđuje izvedena klasa i može nesmetano da je koristi, dok druge
klase, koje nisu deo istog paketa to ne mogu što povećava nivo bezbednosti.
Pravila za pristup zaštićenom elementu su veoma složena i u nekim
slučajevima restriktivna. Zaštićenom članu se može pristupiti iz neke klase
preko reference koja je istog tipa kao data klasa ili tipa neke od njenih potklasa.
Dobar primer koji to ilustruje jeste metoda clone() klase Object, koja je
deklarisana kao protected i koja omogućava pravljenje kopije nekog objekta.
Naime, iako su sve klase potklase klase Object, u nekoj klasi ako je potrebno
kloniranje objekata neophodno je da se implementira interfejs Cloneable i
ponovo definiše metodu clone() kao javna.
Na primer, klasa ArrayList implementira interfejs Cloneable i redefiniše
metodu clone() klase Object, tako da je moguće napisati:

ArrayList list = new ArrayList();


ArrayList list1 = (ArrayList) list.clone();

6.2.4. Modifikator final

Modifikator final može se primeniti na polja, metode i klase. On omogućava


sprečavanje određenih promena, u zavisnosti od konteksta.
Ako se polje prostog tipa obeleži modifikatorom final dobiće se konstantna
vrednost koja ne može da se menja. Ako se polje koje prestavlja referencu na

115
Upotreba klasa

objekat obeleži kao final onda će referenca biti konstantna i kada se jednom
inicijalizuje na neki objekat, ona više ne može da se menja i da pokazuje na
neki drugi objekat. Međutim, sam objekat na koji referenca final pokazuje može
da se menja. Ako se finalno polje ne inicijalizuje prilikom deklarisanja, onda se
ono naziva prazno finalno polje. Prazno finalno polje mora da se inicijalizuje
pre upotrebe, a to može da se uradi u konstruktoru klase. Prazno finalno polje
može da bude rarazličito za objekate klase. Ako su argumenti metode
deklarisani kao final, onda unutar metode nije moguće menjati ono na šta taj
argument ukazuje.
Upotrebom modifikatora final na metode povećava se bezbednost jer se
obezbeđuje njeno nepromenjeno ponašanje prilikom nasleđivanja, ali se
povećava i efikasnost, obzirom da kompajler može poziv toj metodi da ugradi
direktno u kod. Finalna metoda ne može da se menja, odnosno nije moguće
redefinisati tu metodu.
Ako se klasa označi modifikatorom final, onda nijedna klasa ne može da
nasledi tu klasu. Sve metode finalne klase su i same posredno finalne.
Upotreba finalnih klasa optimizuje kod, obzirom da su provere tipova brže ako
su klase final.

6.2.5. Modifikator abstract

Ponekad je potrebno projektovati klasu takvu da objekti njenih potklasa mogu


da pozivaju određenu metodu, a da samoj klasi nije potrebna implementacija te
metode. Namena takvih klasa je da obezbedi zajednički interfejs za sve njene
izvedene klase. Apstrakna klasa omogućava da više klasa rade sa zajedničkim
interfejsom. Apstraktna klasa mora da ima barem jednu metodu koja nije
potpuno definisana, odnosno metodu koja ima samo deklaraciju, a telo nije
definisano. Takva metoda se naziva apstraktna metoda i obeležava se
modifikatorom abstract. Ako klasa ima makar jednu apstraktnu metodu, onda
oma mora da bude kvalifikovana kao abstract.
Kako je svaka apstraktna klasa nepotpuna, to će pokušaj pravljenja objekta
apstraktne klase, od strane kompajlera biti prijavljen kao greška.
Ako neka klasa nasledi apstraktnu klasu, ona mora da obezbedi
implementaciju za svaku njenu apstraktnu metodu. Ako potklasa to ne uradi,
onda i ona mora da bude označena modifikatorom abstract.
Klasa Zivotinja (primer 6.10.) pokazuje upotrebu apstraktnih klasa i apstraktnih
metoda. Klasa Zivotinje disu na istovetan način pa će klasa Zivotinja imati
jednu metodu dise(), koja definiše operaciju disanja. Zivotinje se hrane, ali
različito. Neke životinje su mesožderi, neke biljojedi itd. Zbog te činjenice,
najbolje bi bilo da metoda hraniSe(), koja je svojstvena svim objektima klase
Zivotinja, ali i objektima svih potklasa klase Zivotinja, bude definisana kao
apstraktna.

116
Upotreba klasa

Primer 6.10. Zivotinja.java

abstract class Zivotinja {

public String dise(){


return "DISANJE!";
}
public abstract void hraniSe();
}

Klasa Zivotinja ima dve potklase (slika 6.8).

Slika 6.8.
Klasa Lav (primer 6.11.) nasleđuje klasu Zivotinja, dakle predstavlja
konkretizaciju apstraktnog pojma “zivotinja”, pa mora i da realizuje apstraktnu
metodu hraniSe(), koja je nasleđena iz klase Zivotinja. Klasa Lav nasleđuje i
metodu dise().

Primer 6.11. Lav.java

class Lav extends Zivotinja{


public void hraniSe(){
System.out.println("Lav se hrani mesom!");
}
}

Druga potklasa klase Zivotinja je klasa Krava (primer 6.12.). Klasa Krava
nasleđuje metodu dise(), ali posto se zivotinje koje pripadaju klasi Krava hrane
na drugačiji način od životinja koje pripadaju klasi Lav, klasa Krava realizuje
svoju verziju metode hraniSe(), čija je apstraktna verzija nasleđena iz klase
Zivotinja.

117
Upotreba klasa

Primer 6.12. Krava

class Krava extends Zivotinja {


public void hraniSe(){
System.out.println("Krava se hrani biljkama!");
}
}

Primer 6.13. prikazuje upotrebu klasa Lav i Krava.

Primer 6.13. ZivotinjaPrimer.java

public class ZivotinjaPrimer {


public static void main(String[] arg){
Lav lav = new Lav();
System.out.println("Lav - " + lav.dise());
lav.hraniSe();

Krava krava = new Krava();


System.out.println("Krava - " + krava.dise());
krava.hraniSe();
}
}

6.2.6. Klasa Object

Osnovna klasa svih klasa jeste klasa Object, bez obzira što se ona ne navodi
kao superklasa u deklaraciji neke klase, to kompajler radi automatski. Činjenica
da je klasa Object bazna klasa, dovodi do toga da referenca na objekat bilo
koje klase može da se čuva u promenljivu klase Object. To znači da
promenljiva deklarisana kao objekat klase Object može da čuva vrednost bilo
kog tipa, odnosno da metodi, kojoj je argument tipa Object, može da se
prosledi argument različitog tipa.
Kao potklase klase Object, sve klase nasleđuju metode definisane u klasi
Object. Metode klase Object su date u tabeli 6.2.

118
Upotreba klasa

Metoda Mofifikator Opis


Omogućava kloniranje objekata. Metoda pravi i
clone() protected
vraća kopiju nekog objekta.
Ova metoda se poziva prilikom dealokacije
finalize() protected
memorije odnosno brisanja objekta iz memorije.
Vrši poređenje dva objekta. Ako su objekti jednaki
equals() public
metoda vraća true.
Metoda vraća objekat tipa Class koji vrši
getClass() public
identifikaciju klasedatog objekta.
Vraća heš kod za dati objekat koji se koristi za
hashCode() public
smeštanje objekata u heš kolekcije.
Ova metoda konveruje objekat u tip String. Ova
toString() public metoda se automatski poziva za objekat koji se
spaja sa promenljivom tipa String.
notify() public Koristi se za rad sa nitima.
notifyAll() public Koristi se za rad sa nitima.
wait() public Koristi se za rad sa nitima.
Tabela

6.3. Razlika između nasleđivanja i kompozicije

Mogućnost nasleđivanja osobina i ponašanja jedne klase od strane druge klase


je jedna od najvažnijih osobina objektno orijentisanog programiranja.
Nasleđivanjem se između osnovne i izvedene klase stvara relacija koja može
da se opiše sa “jeste”. Objekat izvedene klase “jeste” tip osnovne klase.
Ova relacija se razlikuje od relacije “ima”, koja se uspostavlja kompozicijom.
Kompozicija označava da jedan objekat koristi drugi objekat, neke druge klase,
za definisanje neke osobine ili za obavljanje neke operacije. U tom slučaju
može se reći da objekat ima referencu na drugi objekat.
Odlučivanje o tome u kom odnosu treba da budu klase u objektno
orijentisanom programiranju je jedan od najvećih problema. Drugim rečima,
dovođenje u ispravan odnos relacija “ima” prema relaciji “je” može biti
povezano sa brojnim problemima.
Na primer, klasa Zaposleni je projektovana kao osnovna klasa koja definiše
svojstva i ponašanja, koja su zajednička za sve zaposlene u kompaniji.
Pojedinačna radna mesta se definišu kao potklase klase Zaposleni. Ovde se
uspostavlja relacija “jeste”, odnosno direktor jeste zaposlen i proizvodni radnik
jeste zaposlen. Međutim, u praksi to i nije dobar pristup jer može, u nekim
slučajevima da dođe do kombinovanja određenih funkcija. Na primer, na
fakultetu asistent može da bude i student doktorskih studija, a profesor može
da bude i dekan, dok u nekoj fabrici inženjer može da ima i neku rukovodeću
funkciju.

119
Upotreba klasa

Bolji pristup podrazumeva projektovanje klase Funkcija. Klasa, kao na primer,


Direktor trebalo bi da nasledi klasu Funkcija. Klasa Zaposleni bi sada trebalo
da bude kompozicija objekata klase Funkcija, pa bi sada bilo izvodljivo
povezati zaposlene sa vremenski ograničenim funkcijama. Sada, klase
Direktor i Zaposleni nisu povezani relacijom “jeste”, već se može reći da
zaposleni može da ma funkciju direktora, ali i druge funkcije.

120
Polimorfizam

POGLAVLJE 7

7. POLIMORFIZAM

7.1. Uvod u polimorfizam

Nasleđivanjem implementacije se stvara nova klasa koja nasleđuje osobine i


ponašanja osnovne klase i na taj način je omogućeno ponovno korišćenje već
definisanih klasa. Međutim, nasleđivanje tipa definiše novu klasu objekata koji
su neka vrsta objekat osnovne klase, odnosno definiše se relacija JE, pa se
objekta izvedene klase može posmatrati da je tipa izvedene klase ili tipa
osnovne klase. Nasleđivanjem implementacije i dodavanjem specifičnosti od
osnovnog tipa stvara se specifičan tip.
Dok enkapsulacija, skrivanjem detalja realizacije odvaja realizaciju od
interfejsa, polimorfizam odvaja klase po tipovima. Polimorfizam, kao
karakteristika objektno orijentisanog programiranja, omogućava da se objekti
specifičnog tipa posmatraju kao objekti osnovnog tipa, ali kada se pozove
operacija za dati objekat onda se poziva operacija za specifičan tip.
Polimorfno ponašanje poziva metode omogućava da jedan tip izrazi svoju
različitost, koja se ispoljava u ponašanju metode koja može da bude pozvana
preko reference tipa osnovne klase.
Na primer, posmatrajmo klasu GeomObjekat i klase Krug i Pravougaonik,
koje nasleđuje klasu GeomObjekat.
Klasa GeomObjekat definiše apstraktnu operaciju povrsina(), koja može da se
konkretizuje samo za određeno geometrijsko telo, pa bi trebalo klasu
GeomObjekat definisati kao apstraktnu.

121
Polimorfizam

Primer 7.1. GeomObjekat.java

abstract class GeomObjekat {

public abstract void povrsina();

Klasa Krug nasleđuje klasu GeomObjekat i definiše privatno polje r tipa int,
kao i realizaciju apstraktne metode povrsina().

Primer 7.2. Krug.java

class Krug extends GeomObjekat {


int r;
public final double pi = 3.14;
Krug(int r){
this.r = r;
}
public void povrsina(){
System.out.println("Povrsina Kruga poluprecnika r = "
+ r+ " je: " + r*r*pi);
}
}

Klasa Pravougaonik nasleđuje klasu GeomObjekat, definiše privatna polja a i


b, tipa int, koja predtsavljaju dimenzije pravougaonika i takođe realizuje
apstraktnu metodu povrsina().

Primer 7.3. Pravougaonik.java

class Pravougaonik extends GeomObjekat {


private int a;
private int b;

Pravougaonik(int a, int b){


this.a = a;
this.b = b;
}

public void povrsina(){


System.out.println("Povrsina pravougaonika stranica a =
"+ a+ " i b = "+ b + " je: " + a*b);
}

122
Polimorfizam

Ako je potrebno izračunati površinu za nekoliko objekta klasa Krug i


Pravougaonik, najlogičnije bi bilo napraviti metodu izracunajPovrsinu(). Ona
kao argument uzima objekat klase Krug i izračunava površinu objekta Krug.
Zatim treba preklopiti metodu izracunajPovrsinu() metodom koja kao
argument ima objekat klase Pravougaonik i koja bi izračunavala površinu
pravougaonika. Ovaj način prikazan je u primeru Povrsina.java.

Primer 7.4. Povrsina.java

public class Povrsina {

public static void izracunajPovrsinu(Krug k){


k.povrsina();
}

public static void izracunajPovrsinu(Pravougaonik p){


p.povrsina();
}

public static void main(String arg[]){


Krug k = new Krug(5);
Pravougaonik p = new Pravougaonik(3,7);
izracunajPovrsinu(k);
izracunajPovrsinu(p);
}
}

Međutim, polimorfizam omogućava da se objekti klasa Krug i Pravougaonik


mogu smatrati i objektima klase GeomObjekat. Moguće je definisati reference
tipa GeomObjekat koje ukazuju na objekte klasa Krug i Pravougaonik, ali
kada se pozove operacija povrsina(), taj poziv će se odnositi na specifičan tip
objekta, a ne na tip reference, pa će se za objekat klase Krug pozvati metoda
povrsina(), koja je definisana u klasi Krug, a za objekat klase Pravougaonik
metoda povrsina() koja je definisana u klasi Pravougaonik (slika 7.1.).

123
Polimorfizam

Slika 7.1.

Sada, postoji jedna metoda izracunajPovrsinu() koja prihvata kao argument


referencu na objekat klase GeomObjekat, ali i svaku referencu na objekat
klase izvedene iz klase GeomObjekat.

Primer 7.5. Povrsina1.java

public class Povrsina1 {

public static void izracunajPovrsinu(GeomObjekat o){


o.povrsina();
}

public static void main(String arg[]){


Krug k = new Krug(5);
Pravougaonik p = new Pravougaonik(3,7);
izracunajPovrsinu(k);
izracunajPovrsinu(p);
}
}

Primena polimorfizma je naročito uočljiva kada se radi sa većim brojem


objekata, koji imaju neke zajedničke osobine, ali se i razlikuju po nekim
specijalnim ponašanjima.

124
Polimorfizam

U klasi Povrsina2, pored polimorfne metode pizracunajPovrsinu(), kojoj se


kao argument može predati objekat klase GeomObjekat, ali i svaki objekat
klase koja je potklasa klase GeomObjekat, defiisana je i metoda izaberi(), koja
na slučajan način kreira ili objekat klase Krug ili objekat klase Pravougaonik.
Referenca na objekat koji se vraća je tipa GeomObjekat.

Primer 7.6. Povrsina2.java

public class Povrsina2 {

public static void izracunajPovrsinu(GeomObjekat o){


o.povrsina();
}

public static GeomObjekat izaberi(){


int slucajanBroj = (int)(Math.random()*2);
if (slucajanBroj == 0){
//Pravimo objekat klase Krug
int slucajnoR = (int)(Math.random()*7);
while (slucajnoR == 0){
slucajnoR = (int)(Math.random()*7);
}
return new Krug(slucajnoR);
} else {
//Pravimo objekat klase Pravougaonik
int slucajnoA = (int)(Math.random()*7);
int slucajnoB = (int)(Math.random()*9);
while (slucajnoA == 0 | slucajnoB == 0){
slucajnoA = (int)(Math.random()*7);
slucajnoB = (int)(Math.random()*9);
}
return new Pravougaonik(slucajnoA, slucajnoB);
}
}

public static void main(String arg[]){


GeomObjekat[] g = new GeomObjekat[11];

for (int i = 0; i < g.length; i++)


g[i] = izaberi();

for (int i = 0; i < g.length; i++){


System.out.print("[" + i + "] ");
izracunajPovrsinu(g[i]);
}
}
}

125
Polimorfizam

U metodi main formira se niz čiji su elementi tipa GeomObjekat, ali i svi objekti
klasa koje su potklase klase GeomObjekat, i kojih ima jedanaest članova.
Dakle, u nizu g nalaze se objekti različitog tipa, ali koji pripadaju zajedničkom
osnovnom tipu. Zahvaljijući polimorfizmu, različiti objekti mogu da se čuvaju u
jednom nizu i mogu da se obrađuju iterativno.
Osnovna klasa GeomObjekat definiše zajednički interfejs za sve objekte
nasleđenih klasa. Izvedene klase redefinišu ove metode da bi obezbedile
ponašanje za specifične objekte.
Statička metoda izaberi() vraća referencu na slučajno izabran geometrijski
objekat. Pri svakoj naredbi return obavlja se svođenje naviše, pa se referenca
na objekat klase Krug ili klase Pravougaonik pretvara u referencu na objekat
klase GeomObjekat, pa se kao povratna vrednost dobija referenca na objekat
klase GeomObjekat.
Kada se iterativno prođe kroz niz g, čiji su elementi objekti klase
GeomObjekat, i pozove metoda izracunajPovrsinu() za svaki objekat, svaki
tip počinje da se pravilno ponaša, odnosno izvršava se operacija specifičnog a
ne osnovnog tipa.
Polimorfizam omogućava da se doda proizvoljan broj geometrijskih objekata,
bez potrebe da se menja metoda izracunajPovrsinu(). Polimorfizam
omogućava proširivost, jer je moguće dodati nove funkcionalnosti. Metode koje
obavljaju posao putem interfejsa osnovne klase, nije potrebno menjati jer one
mogu da rade i sa objektima novih klasa, koje nasleđuju osnovnu klasu.

7.2. Dinamičko razrešavanje poziva metode

Redefinisanje metode omogućava upotrebu metode u potklasi koja ima isto


ime i iste argumente kao metoda u superkalsi. Međutim, redefinisanje metode
osim konvencije koja se tiče imenskog prostora ima daleko veću važnost u
objektno orijentisanom programiranju, odnosno ono predstavlja osnov kedog
od najvažnijih koncepata objektno orijentisanog programiranja, a to je
dinamičko razrešavanje metoda (dynamic method dispatch ili dynamic binding)
ili dinamičko povezivanje.
Dinamičko razrešavanje poziva metode je mehanizam koji omogućava poziv
redefinisanih metoda u vreme izvršavanja, a ne u vreme prevođenja programa.
Dinamičko razrešavanje poziva metode je veoma važan mehanizam, jer se na
njemu zasniva polimorfizam.
Osnova je veoma važan princip: referenca tipa superklase može da čuva i
objekat svake potklase. Ova činjenica je osnova na kojoj se zasniva pozov
redefinisane metode u vreme izvršavanja.

126
Polimorfizam

Kada se poziva redefinisna metoda, Java određuje koja verzija metode će se


koristiti na osnovu tipa objekta na koji se odnosi poziv metode. Ova odluka se
donosi u vreme izvršavanja programa. Kada na objekte različitog tipa ukazuju
reference preko kojih se poziva redefinisana metoda, pozvaće se različite
verzije te metode.
Drugim rečima, tip objekta, a ne tip refrenece, određuje koja verzija
redefinisane metode će biti pozvana. Dakle, ako super klasa definiše metodu
koju potklase redefinišu, onda kada se različiti tipovi objekta referenciraju
referencom tipa superklase i različite verzije redefinisane metode će biti
pozvane.
Dinamičko razrešavanje poziva metode je ilustrovano sledećim primerom.
Data je klasa X, sa samo jednom metodom prikazi(), i klase Y i Z koje
nasleđuju klasu X i redefinišu metodu prikazi().

Primer 7.7. X.java

class X{
public void priazi(){
System.out.println("Metoda prikazi() u klasi X");
}
}

Primer 7.8. Y.java

class Y extends X{
public void priazi(){
System.out.println("Metoda prikazi() u klasi Y");
}
}

Primer 7.9. Z.java

class Z extends X{
public void priazi(){
System.out.println("Metoda prikazi() u klasi Z");
}
}

U klasi RazresavanjePoziva (primer 7.10.) napravljena su tri objekta x, y i z,


koji su tipa X, Y i Z. Zatim, deklarisana je referenca ref na objekat klase X.

127
Polimorfizam

Program, dalje sukcesivno dodeljuje referencu na sva tri napravljena objekta


promenljivoj ref, koja se koristi za pozivanje metode prikazi().

Primer 7.10. RazresavanjePoziva.java

public class RazresavanjePoziva {


public static void main(String[] arg){
X x = new X();
Y y = new Y();
Z z = new Z();

// rerenca na objekat klase X


X ref;

// ref ukazuje na objekat tipa X


ref = x;
ref.priazi();

// ref ukazuje na objekat tipa Y


ref = y;
ref.priazi();

// ref ukazuje na objekat tipa Z


ref = z;
ref.priazi();
}
}

Rezultat izvršavanja programa (slika 7.2.), verzija redefinisane metode


prikazi(), koja se poziva određena je tipom objekta koji je referenciran u
trenutku pozivanja, a ne tipom reference ref. Ako bi poziv bio određen tipom
referentne promenljive onda bi u sva tri slučaja bila pozvana metoda prikazi()
koja je definisana u klasi X.

Slika 7.2.

128
Polimorfizam

7.3. Proširivanje programa

Polimorfizam omogućava proširivanje programa, dodavanjem novih klasa, bez


potrebe menjanja metoda, kojima se kao argument prosleđuje referenca na
objekat Osnovne klase. Tako, na primer, u programu koji radi sa geometrijskim
objektima, moguće je proširiti, na primer klasu Trougao i dobiti klase
PlaviTrougao i CrveniTrougao, a da pri tome nema potrebe menjati metodu
izracunajPovrsinu(). Dijagram hijerarhije je prikazan na slici 7.3.

Slika 7.3.

Realizacija izmena programa, koje su naznačene na dijagramu hijerarhije, uz


nove klase, prikazana je u sledećem primeru 7.11.

Primer 7.11. ProsirivanjePrograma.java

public class ProsirivanjePrograma {


public static void izracunajPovrsinu(GeomObjekat o){
o.povrsina();

129
Polimorfizam

public static GeomObjekat izaberi(){


if((int)(Math.random()*2) == 0){
//Pravimo objekat klase Krug
if((int)(Math.random()*2) == 0){

int slucajnoR = (int)(Math.random()*7);


while (slucajnoR == 0){
slucajnoR = (int)(Math.random()*7);
}
return new PlaviKrug(slucajnoR);

} else {
int slucajnoR = (int)(Math.random()*7);
while (slucajnoR == 0){
slucajnoR = (int)(Math.random()*7);
}
return new CrveniKrug(slucajnoR);
}

} else {
//Pravimo objekat klase Pravougaonik
int slucajnoA = (int)(Math.random()*7);
int slucajnoB = (int)(Math.random()*9);
while (slucajnoA == 0 | slucajnoB == 0){
slucajnoA = (int)(Math.random()*7);
slucajnoB = (int)(Math.random()*9);
}
return new Pravougaonik(slucajnoA, slucajnoB);
}
}

public static void main(String arg[]){


GeomObjekat[] g = new GeomObjekat[11];

for (int i = 0; i < g.length; i++)


g[i] = izaberi();

for (int i = 0; i < g.length; i++){


System.out.print("[" + i + "] ");
izracunajPovrsinu(g[i]);
}
}
}

abstract class GeomObjekat {

public abstract void povrsina();

class Krug extends GeomObjekat {

130
Polimorfizam

protected int r;
public final double pi = 3.14;
Krug(int r){
this.r = r;
}
public void povrsina(){
System.out.println("Povrsina Kruga poluprecnika r = "
+ r+ " je: " + r*r*pi);
}
}

class Pravougaonik extends GeomObjekat {


private int a;
private int b;

Pravougaonik(int a, int b){


this.a = a;
this.b = b;
}

public void povrsina(){


System.out.println("Povrsina pravougaonika stranica a
= "+ a+ " i b = "+ b + " je: " + a*b);
}
}

class PlaviKrug extends Krug {

PlaviKrug(int r){
super(r);
}

public void povrsina(){


System.out.println("Povrsina Plavog Kruga poluprecnika
r = " + r + " je: " + r*r*pi);
}
}

class CrveniKrug extends Krug {

CrveniKrug(int r){
super(r);
}

public void povrsina(){


System.out.println("Povrsina Crvenog Kruga
poluprecnika r = " + r + " je: " + r*r*pi);
}
}

131
Polimorfizam

Kad god se u niz g, u klasi main(), ubaci novi element vrši se svođenje naviše
ka klasi GeomObjekat. Metoda izracunajPovrsinu() ostaje nepromenjena. To
je i najvažnija funkcija polimorfizma, da rzdvoji promenljive od nepromenljivih
stvari.

7.4. Polimorfizam i konstruktori

Kao što je objašnjeno u prethodnom poglavlju, svaki konstruktor ima tri faze.
Prvo se poziva eksplicitno ili implicitno konstruktor superklase, zatim se
inicijalizuju polja, redolsedom kojim su deklarisana, kao i blokovi za
inicijalizaciju i na kraju se izvršava telo konstruktora.
Potklasa ima pristup svojim poljima, ređe poljima superklase pošto su ona
obično privatna. Samo konstruktor natklase ima pravo pristupa i mogućnost
inicijalizacije elemenata te klase. Kako objekat potklase sadrži podobjekat
superklase, neophodno je da se pozovu svi konstruktori da bi se pravilno
izvršila inicujalizacija. Ako se u konstruktoru izvedene klase izričito ne pozove
konstruktor superklase, prevodilac će automatski da pozove podrazumevani
konstruktor, a ako takvog konstruktora nema, doći će do greške.
Uticaj polimorfizma, nasleđivanja i kompozicije na redosled pozivanja
konstruktora, prikazan je u sledećem primeru.
Složena klasa KafaZaPoneti nasleđuje klasu Kafa i sastoji se od klasa Casa i
Secer. Svaki konstruktor ispisuje poruku kada se pozove. Ova klasa
objedinjuje tri nivoa nasleđivanja i dva objekta člana.

Primer 7.12. KafaZaPoneti.java

public class KafaZaPoneti extends Kafa {


Casa c = new Casa();
Secer s = new Secer();
KafaZaPoneti(){
System.out.println("KafaZaPoneti()");
}
public static void main(String[] arg){
new KafaZaPoneti();
}
}

class Casa {
Casa(){
System.out.println("Casa()");
}
}

132
Polimorfizam

class Secer {
Secer(){
System.out.println("Secer()");
}
}

class Pice {
Pice(){
System.out.println("Pice()");
}
}

class ToploPice extends Pice{


ToploPice(){
System.out.println("ToploPice()");
}
}

class Kafa extends ToploPice{


Kafa(){
System.out.println("Kafa()");
}
}

Rezultat izvršavanja program je prikazan na slici 7.4.

Slika 7.4.

Na osnovu rezultata izvršavanja programa, redosled pozivanja konstruktora u


složenoj klasi je prikazan na slici 7.5.

133
Polimorfizam

Slika 7.5.

Ako se polimorfna metoda pozove iz konstruktora, biće pozvana redefinisana


verzija te metode. Efekat može biti neočekivan, naime, ako se pozove metoda
izvedene klase, a ako je poznato da se prvo vrši konstrukcija objekta osnovne
klase, može se desiti da se pozove metoda čiji članovi možda još uvek nisu
inicijalizovani. To može da dovede do velikih do problema.
Sledeći primer ilustruje ovaj scenario:

Primer 7.13. CrtajKrug.java

public class CrtajKrug {

public static void main(String[] arg){


Krug k = new Krug(7);
k.crtaj();
}
}

class Oblik {
Oblik(){
System.out.println("Oblik() pre poziva crtaj()");
crtaj();
System.out.println("Oblik() posle poziva crtaj()");
}
void crtaj(){
System.out.println("Crtaj oblik ");
}
}

class Krug extends Oblik {


int r = 1;
Krug(int r){
this.r = r;
System.out.println("Krug(), precnik = " + this.r);

}
void crtaj(){

134
Polimorfizam

System.out.println("Krug.crtaj(), precnik = " +


this.r);
}
}

Klasa Krug nasleđuje klasu Oblik i redefiniše metodu crtaj() ali, metodu crtaj()
poziva konstruktor osnovne klase Oblik. Pošto se polimorfna metoda poziva iz
konstruktora, biće pozvana redefinisana metoda. Kako se prvo poziva
konstruktor superklase, u trenutku poziva redefinisane metode crtaj(), polje r
još uvek neće biti inicijalizovano, pa će se i pozvati redefinisana metoda crtaj
za poluprecnik r = 0.
Rezultat je sledeći:

Slika 7.6.

Prema tome, redosled pozivanja konstruktora u složenim klasama koje


kombinuju kompoziciju, nasleđivanje i polimorfizam je sledeći:
1. Memorijski prostor za smeštanje objekata inicijalizuje se binarnim
nulama.
2. Pozivaju se eksplicitno ili implicitno konstruktori superklase.
3. Inicijalizuju se članovi klase, redolsedom kojim su deklarisani, kao i
blokovi za inicijalizaciju.
4. Na kraju se izvršava telo konstruktora.
Iz ovog primera, treba zaključiti da u konstruktorima treba izbegavati pozive
drugih metoda. Bez opasnosti se mogu pozivati samo metode koje u
deklarisane modifikatorom final, jer one ne mogu da se redefinišu.

135
Polimorfizam

136
Interfejsi

POGLAVLJE 8

8. INTERFEJSI

Klasa je osnovna jedinica koja omogućava implementaciju principa OOP.


Osnovna jedinica objektno orijentisanog dizajna jeste tip. Klasa definiše novi
tip, kombinujući dizajn i implementaciju. Međutim, nekad je potrebno definisati
nove tipove bez implementacije. To omogućavaju interfejsi, koji definišu tipove
u apstraktnom obliku. Osnovna uloga interfejsa jeste definisanje skupa metoda,
bez implementacije, koje mogu da se implementiraju u drugim klasama i da se
pozivaju polimorfno. Sve te klase imaće isti interfejs, a polimorfno pozivanje
metoda biće moguće korišćenjem reference tipa datog interfejsa.
Klasa može da nasleđuje svojstva i ponašanja druge klase ali, u Java
programskom jeziku moguće je samo jednostruko nasleđivanje, što znači da
klasa može da ima samo jednu super klasu. Međutim, ponekad je potrebno
kombinovati ponašanja iz dve ili više klasa da bi se dobila željena klasa. Drugi
programski jezici, kao C++, ovaj problem mogu da reše korišćenjem
višestrukog nasleđivanja, međutim, sa višestrukim nasleđivanjem problemi
pozivanja nasleđenih metoda i organizacija hijerarhije klasa postaju
komplikovaniji. Rešavanje ovog problema komplikuje projektovanje i upotrebu
hijerarhije klasa. Zbog toga se u Javi koristi samo jednostruko nasleđivanje, a
problem hijerarhije klasa sa izmešanim ponašanjem rešava se korišćenjem
interfejsa. Java klasa može da nasledi više interfejsa, ali mora da obezbedi
implementaciju svih metoda nasleđenog interfejsa.
Interfejs je zbirka apstraktnih ponašanja koja mogu biti implementirana u bilo
koju klasu, da bi klasa dobila ponašanja koja nije nasledila od svoje
superklase.
Java interfejsi specificiraju samo dizajn klase, a ne i implementaciju, što znači
da interfejsi sadrže samo definicije metoda i konstanti.
Interfejsi podržavaju dinamičko razrešavanje metoda u trenutku izvršavanja
programa.

137
Interfejsi

8.1. Deklarisanje interfejsa

Interfejs se deklariše korišćenjem ključne reči interface, davanjem imena


interfejsu i navođenjem članova interfejsa između vitičastih zagrada:

public interface imeInterfejsa {


//ako se definisu podaci, oni moraju biti konstante
tip imePolja = konst_izr;
//metode moraju biti apstraktne
povratniTip imeMetode (argumenti);
}

Interfejs se pravi tako što se umesto ključne reči class upotrebi ključna reč
intrface. Ispred reči interface može da stoji i reč public, ako je dati interfejs
definisan u datoteci sa istim imenom. Ako je izostavljen modifikator pristupa,
onda je interfejs prijateljski i može da se koristi samo unutar istog paketa.
Članovi interfejsa mogu da budu:
 polja (konstante),
 metode bez implementacije i
 ugnežđene klase i interfejsi.
Svi članovi interfejsa su implicitno javni, ali se prema konvenciji modifikator
public se izostavlja.
Interfejs može da deklariše imenovane konstante. Ove konstante se definišu
kao polja ali su implicitno public, static i final i ova polja moraju da se
inicijalizuju.
Metode deklarisane u interfejsu su implicitno abstaract i public. Iza zaglavlja
metode navodi se tačka i zarez i one ne mogu biti statičke kao ni final, jer još
nisu implementirane.

8.2. Implementiranje interfejsa

Interfejs definiše specifikaciju za mnoge moguće implementacije. On definiše


ugovor koji pokazuje način interakcije sa nekim objektom i razdvaja
specifikaciju naćina korišćenja od implementacije, što je i cilj objektno
orijentisanog programiranja.
Za razliku od klase, koja se nasleđuje, interfejs se implementira. Sintaksa
implementacije interfejsa je sledeća:

138
Interfejsi

class imeKlase implements imeInterfejsa {


// Polja klase imeKlase
// Metode klase ImeKlase
// Metode interfejsa imeInterfejsa koje klasa
// mora da implementira
}

Interfejs FaktorKonverzije (primer 8.1.) definiše samo polja, koja su implicitno


public, static i final. Kako su ova polja konstantna i statična ona moraju i da
se inicijalizuju. Interfejs je deklarisan kao public, što znači da konstante
definisane u njemu mogu da se koriste i van paketa u kome je on definisan.

Primer 8.1. FaktorKonverzije.java

public interface FaktoriKonverzije {


double EUR_USD = 1.3062;
double USD_EUR = 0.76558;
double EUR_RSD = 105.6804;
double RSD_EUR = 0.00941;
double USD_RSD = 80.9067;
double RSD_USD = 0.01229;
}

Konstantama definisanim u interfejsu moguće je pristupiti kvalifikovanjem


imena polja imenom interfejsa (primer 8.2.), kao i statičkoj promenljivoj.

Primer 8.2. PrimerKonvertor.java

class PrimerKonvertor {
public static void main(String[] arg){
System.out.println("EUR_USD = "+
FaktoriKonverzije.EUR_USD);
System.out.println("EUR_RSD = "+
FaktoriKonverzije.EUR_RSD);
System.out.println("USD_RSD = "+
FaktoriKonverzije.EUR_USD);
}
}

Ako se klasa deklariše tako da implementira interfejs FaktoriKonverzije, tada


ona može da pristupa konstantama, kao da su njeni članovi, korišćenjem
nekvalifikovanih imena (primer 8.3.).

139
Interfejsi

Primer 8.3. PrimerKonvertor.java

class PrimerKonvertor implements FaktoriKonverzije{


public static void main(String[] arg){
System.out.println("EUR_USD = "+ EUR_USD);
System.out.println("EUR_RSD = "+ EUR_RSD);
System.out.println("USD_RSD = "+ USD_RSD);
}
}

Definisanjem skupa metoda, u apstraktnom obliku, interfejs definiše određenu


funkcionalnost u objektima klasa koje implementiraju taj interfejs. Interfejs
Konvertor (primer 8.4.) se dobija tako što se interfejsu FaktorKonverzije
dodaje šest metoda, koje služe za konvertovanje valuta.

Primer 8.4. Konvertor.java

public interface Konvertor {


double EUR_USD = 1.3062;
double EUR_RSD = 105.6804;
double USD_EUR = 0.76558;
double USD_RSD = 80.9067;
double RSD_EUR = 0.00941;
double RSD_USD = 0.01229;

double eur_usd(double eur);


double eur_rsd(double eur);
double usd_eur(double usd);
double usd_rsd(double usd);
double rsd_eur(double rsd);
double rsd_usd(double rsd);
}

Svaka metoda koja je deklarisana u interfejsu Konvertor mora da bude


definisana u klasi koja implementira taj interfejs. Tako na primer, klasa
KonvertorValuta (primer 8.5.) implementira interfejs Konvertor. Kako su
metodi u interfejsu javne, prilikom njihove implementacije u klasi
KonvertorValuta mora da se koristi reč public. U implementaciji metoda u
klasi ne sme da se koristi restriktivniji modifikator pristupa od onog koji se
implicitno koristi u definiciji apstraktnih metoda, a public modifikator pristupa je
najmanje restriktivan.

140
Interfejsi

Primer 8.5. KonvertorValuta.java

public class KonvertorValuta implements Konvertor {

public double eur_usd(double eur){


return eur*EUR_USD;
}

public double eur_rsd(double eur){


return eur*EUR_RSD;
}

public double usd_eur(double usd){


return usd*USD_EUR;
}

public double usd_rsd(double usd){


return usd*USD_RSD;
}

public double rsd_eur(double rsd){


return rsd*RSD_EUR;
}

public double rsd_usd(double rsd){


return rsd*RSD_USD;
}
}

Upotreba klase KonvertorValuta, koja implementira interfejs Konvertor data


je u primeru KonvertorValutaPrimer.java.

Primer 8.6. KonvertorValutaPrimer.java

import java.text.*;
public class KonvertorValutaPrimer {
public static void main(String[] arg){
KonvertorValuta kv = new KonvertorValuta();
DecimalFormat df = new DecimalFormat("#.##");

System.out.println("70 EUR = " +


df.format(kv.eur_rsd(70)) + " RSD");
System.out.println("5768 RSD = " +
df.format(kv.rsd_eur(5768)) + " EUR");
System.out.println("120 USD = " +
df.format(kv.usd_rsd(120)) + " RSD");
}
}

141
Interfejsi

Klasa koja implementira neki interfejs meže i da izostavi implementaciju neke


metode, ali u tom slučaju klsa od interfejsa nasleđuje apstraktne metode i mora
da bude deklarisana kao apstraktna. Takva klasa ne može da ima instance,
već može da bude samo superklasa nekoj konkretnoj klasi, koja bi morala da
implementira preostale metode interfejsa.

8.3. Nasleđivanje interfejsa

Između postupka proširivanja klasa i proširivanja interfejsa nema neke razlike.


Interfejs se nalseđuje korišćenjem ključne reči extends. Na primer, interfejs
Konvertor ne bi morao da definiše konstante konverzije, već bi mogao da
nasledi interfejs FaktoriKonverzije (primer 8.7.).

Primer 8.7. Konvertor.java

public interface Konvertor extends FaktoriKonverzije {

double eur_usd(double eur);


double eur_rsd(double eur);
double usd_eur(double usd);
double usd_rsd(double usd);
double rsd_eur(double rsd);
double rsd_usd(double rsd);
}

Kako interfejs nema realizaciju moguće je kombinovati više interfejsa.


Ovakvo kombinovanje interfejsa naziva se višestruko nasleđivanje, jer u tom
slučaju možemo za neki objekat da kažemo da je i tipa a i tipa b i tipa c...
Višestruko nasleđivanje pomoću interfejsa omogućava da se kombinuju
ponašanja, ali realizaciju može da ima samo jedna klasa.
Interfejsi omogućavaju svođenje naviše ka više prostih tipova (slika 8.1.).

142
Interfejsi

Slika 8.1.

Na dijagramu (slika 8.1.), klase DomaceZivotinje i DivljeZivotinje (primer


8.9.) nasleđuju apstraktnu klasu Zivotinje (primer 8.8.) i definišu realizaciju
apstraktne metode hraniSe(). Višestruko nasleđivanje, kombinovanjem
ponašanja interfejsa MozeDaCuva (primer 8.11.) i MozeDaTrci (primer 8.13.) i
klase DomaceZivotinje (primer 8.9.), prikazano je na primeru klase Pas
(primer 8.14.). Takođe, klasa Vuk (primer 8.15.) nasleđuje ponašanja i
realizaciju klase DivljeZivotinje, kao i ponašanja definisana u interfejsima
MozeDaTrci i MozeDaLovi (primer 8.12.).

Primer 8.8. Zivotinja.java

abstract class Zivotinja {

public String dise(){


return "DISANJE!";
}
public abstract void hraniSe();
}

143
Interfejsi

Primer 8.9. DomacaZivotinja.java

public class DomacaZivotinja extends Zivotinja {


public void hraniSe(){
System.out.println("Hrani je covek!");
}
}

Primer 8.10. DivljaZivotinja.java

public class DivljaZivotinja extends Zivotinja {


public void hraniSe(){
System.out.println("Hrani se sama!");
}
}

Primer 8.11. MozeDaCuva.java

public interface MozeDaCuva {


void cuva();
}

Primer 8.12. MozeDaLovi.java

public interface MozeDaLovi {


void lovi();
}

Primer 8.13. MozeDaTrci.java

public interface MozeDaTrci {


void trci();
}

Primer 8.14. Pas.java

public class Pas extends DomacaZivotinja implements MozeDaCuva,


MozeDaTrci{
public void cuva(){
System.out.println("Pas cuva kucu!!!");
}

144
Interfejsi

public void trci(){


System.out.println("Pas trci!!!");
}
}

Primer 8.15. Vuk.java

public class Vuk extends DivljaZivotinja implements MozeDaLovi,


MozeDaTrci{
public void lovi(){
System.out.println("Vuk lovi!!!");
}

public void trci(){


System.out.println("Vuk trci!!!");
}
}

Klasa PrimerZivotinje (primer 8.16.) definiše polimorfne metode hrana(),


trcanje() i disanje(). Metodi hrana() može da se prosledi, kao argument,
referenca na objekat tipa Zivotinje, kao i svi objekti klasa koje nasleđuju klasu
Zivotinje, a to su objekti klasa DomaceZivotinje, DivljeZivotinnje, Pas i Vuk.
Klasa Pas implementira interfejse MozeDaTrci i MozeDaCuva, pa se objekti
klase Pas, kao argumenti, mogu proslediti metodama trcanje() i cuvaKucu().
Klasa Vuk implementira interfejse MozeDaTrci i MozeDaLovi, pa se objekti
klase Vuk, mogu proslediti metodama trcanje() i lov().

Primer 8.16. Primer.Zivotinje.java

public class PrimerZivotinje {


public static void main(String[] arg){
Pas p = new Pas();
cuvaKucu(p);
hrana(p);
disanje(p);
trcanje(p);

Vuk v = new Vuk();


lov(v);
hrana(v);
disanje(v);
trcanje(v);
}

145
Interfejsi

static void cuvaKucu(MozeDaCuva m){


m.cuva();
}

static void lov(MozeDaLovi m){


m.lovi();
}

static void hrana(Zivotinja z){


z.hraniSe();
}

static void disanje(Zivotinja z){


System.out.println(z.dise());
}

static void trcanje(MozeDaTrci t){


t.trci();
}
}

8.4. Razlika između apstraktne klase i interfejsa

Interfejsi obezbeđuju jedan oblik višestrukog nasleđivanja jer je moguće


implementirati više interfejsa, dok klasa može da nasledi samo jednu klasu.
Apstraktna klasa može da ima delimičnu implementaciju, zaštićene delove,
statičke metode itd., dok su interfejsi ograničeni samo na javne konstante i
javne metode bez implementacije.

146
Izuzeci

POGLAVLJE 9

9. IZUZECI

Neke greške se ne mogu otkriti prilikom kompajliranja programa. Takve greške,


pri određenim okolnostima, mogu da da dovedu do ozbiljnih problema, a
izuzeci definišu način za signalizaciju takvih problema, koji mogu da se dogode
u vreme izvršavanja programa. Kada se problem pojavi, obradu preuzima
mehanizam za obradu izuzetaka, koji zna kako i na koji način da obradi
problem, a da program ne prekine svoje izvršavanje. Izuzeci, takođe,
pojednostavljuju postupak za obradu greške lokalizovanjem koda za obradu
greške na jednom mestu u bloku za obradu greške.
Izuzetak je objekat koji, koji se kreira kada nastupi neuobičajena situacija i on
ima tip, metode i polja. U poljima ovog objekta čuvaju se informacije i detalji
nastalog problema.
Kada se dogodi neka greška u nekoj metodi, metoda kreira objekat izuzetka
koji sadrži informacije o grešci. Kontrolu izvršavanja preuzima mehanizam
obrade izuzetka. Kreiranje izuzetka i predavanje kontrole izvršavanja
mehanizmu za obradu greške naziva se bacanje izuzetka (throwing
exception). Situacije koje mogu da generišu izuzetke uglavnom mogu da budu
greške u kodu ili podacima, kao što je korišćenje neodgovarajućeg indeksa,
neispravna konverzija ili deljenje nulom, zatim izuzeci u standardnim
metodama, korisnički definisani izuzeci i greške Java virtuelne mašine.
Kada metoda baci izuzetak, izvršni sistem pokušava da nadje nekog ko bi
mogao da obradi taj izuzetak. Skup mogućih entiteta koji bi mogli da obrade
izuzetak jesu metode, koje su bile pozvane dok nije pozvana metoda gde se
desila greška. Lista ovih metoda je poznata kao call stack (slika 9.1.).

147
Izuzeci

Slika 9.1.

Izvršni sistem pretražuje call stack, tražeći blok koda koji može da obradi
izuzetak. Taj blok koda se zove rukovalac izuzetkom. Pretraživanje počinje
metodom gde se dogodila greška i nastavlja kroz listu call stack u reverznom
redosledu, u odnosu na pozive metoda (slika 9.2.).
Kada se pronađe odgovarajući rukovalac izuzetkom, izvršni sistem predaje
izuzetak rukovaocu. Rukovalac izuzetkom odlučuje da uhvati izuzetak (catch
exception). Ako izvršni sistem ne pronađe odgovarajućeg rukovaoca
izuzetkom, prestaje sa radom.

Slika 9.2.

148
Izuzeci

9.1. Vrste izuzetaka

Svaki objekat izuzetka je primerak klase koja je potklasa klase Throwable.


Izuzeci se zatim granaju u grupu izuzetaka koja je definisana klasom
Exception i grupu predstavljenu klasom Error.
Klasa Exception određuje sve izuzetke koji se mogu pojaviti u korisničkim
programima. Klasom Error su definisani svi izuzeci koji zavise od izvršnog
okruženja u kome se izvršavaju programi.
Sve izuzetke možemo podeliti u dve grupe:
 Provereni izuzeci
 Neprovereni izuzeci
Prvu grupu izuzetaka čine provereni izuzeci. To su greške koje programer
može da predvidi i da ih obradi. Na primer, može se desiti da program zahteva
otvaranje datoteke koja ne postoji.
Svi izuzeci su provereni, osim izuzetaka koji nasleđuju klase Error i
RuntimeException i oni se nazivaju neprovereni izuzeci.

Slika 9.3.

9.1.1. Izuzeci tipa Error

Objekti klase Error predstavljaju stanja za koja se od korisnika ne očekuje da


išta uradi, tj. izuzeci ovog tipa se ne hvataju. Klasa Error ima tri direktne
potklase:
 ThreadDeath
 LinkageError – ozbiljni problemi sa klasama u programu kao što su
nekompatibinost među klasama ili pokušaj kreiranja objekta
nepostojećeg klasnog tipa.

149
Izuzeci

 VirtualMachineError – greške JVM-a.


Objekti izuzetka klase ThreadDeath nastaju kada se nit koja se izvršava
namerno stopira. Ako se nit izvršavanja ispravno uništi, ovaj tip izuzetka neće
biti izbačen.
Klasa LinkageError definiše objete izuzetaka koji predstavljaju ozbiljne
probleme sa klasama u programu kao što su nekompatibinost među klasama ili
pokušaj kreiranja objekta nepostojećeg klasnog tipa.
Klasom VirtualMachineError specificiraju se izuzeci koji predstavljaju veoma
velike probleme u radu Java vituelne mašine.
U ovakvim situacijama jedino što je moguće uraditi jeste pročitati poruku o
grešci.

9.1.2. Izuzeci tipa RuntimeException

Ukoliko u programu postoji metoda koja može da izbaci izuzetak tipa koji
predstavlja potklasu klase Exception, onda taj izuzetak mora da se obradi u toj
metodi ili data metoda treba da se deklariše da može da izbaci dati izuzetak.
Ako se ne učine jedna od ove dve stvari, kod neće moći da se kompajlira.
Ovo ne važi za izuzetke tipa RuntimeException. Metoda koja može da izbaci
izuzetak ovog tipa ne mora da se deklariše da može da izbaci taj izuzetak, niti
u metodi treba definisati rukovaoca izuzetkom.
Objekti klase RuntimeException definišu interne uslove izuzetaka, koje
aplikacija uobičajeno ne očekuje i od kojih se ne može oporaviti. To su obično
programerske greške, kao što je loša eksplicitna konverzija ili pristup
elementima niza izvan granice niza ili neinicijalizovanoj referenci, odnosno to
su logičke greške ili nepropisno korišćenje API-ja.
Postoji veliki broj klasa, koje su podklase klase RuntimeException, i koje se
koriste se za definisanje problema u različitim Java bibliotekiama. U paketu
java.lang definisane su sledeće klase izuzetaka, koje su potklase klase
RuntimeException:
 ArithmeticException – pokušaj nedozvoljene aritmetičke operacije,
na primer, deljenje nulom
 IndexOutOfBoundsException – indeks je van dozvoljenih granica
objekta, koji može biti niz, String ili Vector.
 NegativeArraySizeException – pokušaj definicije niza sa negativnim
indeksom.
 SecurityException - pokušaj narušavanja sigurnosnih pravila (security
manager).

150
Izuzeci

 NullPointerException – upotreba promenljive koja sadrži null umesto


da referiše na konkretan objekat.
 ClassCastException – pokušaj kastovanja objekta u nekorektni tip.
 IllegalArgumentException – argument prosleđen metodi nije
korektnog tipa.
 UnsupportedOperationException – zahtevana operacija nije
podržana.
 ArrayStoreException - pokušaj dodeljivanja reference pogrešnog tipa
elementu niza.

9.1.3. Provereni izuzeci

Ako je moguće da se u nekoj metodi dogodi neki provereni izuzetak, onda


treba pokušati da se uhvati i obradi taj izuzetak ili tu metodu deklarisati da
može da izbaci provereni izuzetak.
Ako se ne deklariše metoda da može da izbaci provereni izuzetak ili se ne
definiše rukovalac izuzetkom u toj metodi, onda će kompajler da prijavi grešku.
Osim nekoliko izuzetaka koji su tipa potklase klase RuntimeException, svi
ostali izuzeci koji se moraju obraditi u Java programima su provereni izuzeci.
Ako u nekoj metodi može da se dogodi neki neočekivani događaj koji može da
kreira objekat izuzetka tipa koji nije objekat klase RuntimeException ili klase
Error i ako se taj izuzetak ne obradi u toj metodi, onda ta metoda treba da se
deklariše da može da izbaci taj izuzetak.
Deklarisanje metode da može da ispali neki izuzetak vrši se u zaglavlju
metode, dodavanjem klauzule throws.
Ako na primer, metoda citajDatoteku() može da generiše izuzetak tipa
IOException, onda se ona deklariše na sledeći način:

public void citajDatotrku() throws IOException {


// Kod metode
}
Na ovaj način saopštava se da kod u metodi citajDatoteku() može, pored
svoje uobičajene aktivnosti, da dovede i do nezgodne situacije kada će se
izbaciti izuzetak tipa IOException. Metoda koja poziva metodu citajDatoteku()
je obaveštena da može doći do izuzetka tipa IOException, pa pozivajući kod

151
Izuzeci

treba da sadrži deo za obradu tog izuzetka ili i ta sama mateoda treba da bude
deklarisana da može da vrati objekat izuzetka tipa IOException.
Ako u nekoj metodi postoji kod koji može da dovede do izbacivanja više
izuzetaka različitih tipova, onda u deklaraciji te metode iza reći throws treba
navesti listu tipova mogućih izuzetaka.
Na primer:

public void citajDatotrku() throws IOException,


FileNotFoundException {
// Kod metode
}

9.2. Obrada izuzetka

Kada se u programu dogodi greška, metoda u kojoj je nastala greška izbacuje


izuzetak koji odgovara problemu koji se desio. Da program ne bi krahirao
potrebno je ‘uhvatiti’ taj izuzetak i obraditi ga. Obrada izuzetka se obavlja u
bloku koda koji se zove rukovalac izuzetkom. Rukovalac izuzetkom se sastoji
od klauzula try-catch-finally.
Kod za koji se sumnja da može da izbaci izuzetak stavlja se u blok try.
Izbačeni izuzetak se hvata i obrađuje klauzulom catch. U bloku finally izvršava
se kod bez obzira da li je izuzetak izbačen ili ne.
Opšti oblik blokova try-catch-finali je dat u nastavku:

try {
// kod koji moze da generise izuzetak
} catch (TipIzuzetka e) {
// Obrada izuzetaka koji uhvacen
} finally {
// kod joji se izvrsava ako izuzetak
// nije uhvacen
}

Prvi korak u formiranju rukovaoca izuzetkom jeste stavljanje bloka koda, koji bi
mogao da izazove izuzetak u blok try:

152
Izuzeci

try {
// kod koji može da izazove izuzetak;
}

Segment koda je kod koji sadrži jednu ili više legalnih komandi koje bi mogle
da izbace izuzetak.
Kod koji može da izbaci izuzetak e tipa TipIzuzetka, koji mora da bude
potklasa klase Throwable, stavlja se u blok koji je označen ključnom rečju try.
Ako dati kod izbaci izuzetak definisanog tipa, onda se ostatak koda u bloku try
preskače i izvršava se kod unutar bloka catch. Svaki catch blok rukuje tipom
izuzetka koji je specificiran argumentom. Tip argumenta TipIzuzetka, deklariše
tip izuzetka i mora biti objekat potklase klase Throwable.

} catch (TipIzuzetka1 e1) {


// Obrada izuzetaka e1
} catch (TipIzuzetka1 e2) {
// Obrada izuzetaka e2
}
Blok catch može da rukuje sa više tipova izuzetaka:

} catch (TipIzuzetka1 | TipIzuzetka2 e) {


// Obrada izuzetaka
}

Ako catch rukuje sa više tipova izuzetka, tada je catch parametar implicitno
final.
Ako kod unutar bloka try ne izbaci izuzetak, onda se izvršava kod unutar bloka
try, a kod unutar bloka catch se preskače. Ako kod unutar bloka try izbaci
izuzetak koji nije tipa TipIzuzetka, onda metoda momentalno prekida sa
radom.
Kada kod za obradu izuzetaka, unutar bloka try, uhvati izuzetak obrada se
nastavlja unutar bloka catch, a kada ne uhvati izuzetak blok try se završava, a
blok catch se preskače. Problem nastaje ako je metoda zauzela neke resurse i
ako ti resusrsi treba da se oslobode. U tom slučaju kod za oslobađanje resursa

153
Izuzeci

bi trebalo napisati na dva mesta, u običnom kodu i u kodu za obradu izuzetaka.


Mehanizam za obradu grešaka nudi bolje rešenje u vidu bloka finally.
Blok finally se uvek izvršava kada postoji try blok, on se izvršava i ako se desi
izuzetak ali i ako se izuzetak ne desi. blok finally je ključno sredstvo za
sprečavanje curenja resursa.
Ako na primer, neki kod pokušava da pročita neku tekstualnu datoteku, sam
pokušaj čitanja datoteke može da izazove grešku zbog ulazno-izlaznih
operacija. Pošto je taj deo koda rizičan stavlja se u blok try. Ako se dogodi
greška izbacuje se izuzetak koji se hvata u bloku catch i obrađujemo.
Zatvaranje datoteke je potrebno izvršiti bez obzira da li je datoteka uspešno
pročitana ili se dogodila U/I greška. Zato se kod koji zatvara datoteku stavlja u
blok finally.

...
try {
readTextFile();
} catch (IOException e) {
// Obrada izuzetaka koji nastaju sa U/I aktivnostima
} finally {
closeTextFile();
}
...

Blok finally može da dovede do nepredvidivih rezultata ako koristi naredbu


return. Ako se naredba return koristi i u try bloku i u bloku finally, onda može
da se desi da naredba return u finally bloku maskira originalnu vraćenu
vrednost. To je ilustrovano u primeru 9.1.

Primer 9.1. PrimerFinally.java

public class PrimerFinally {


public static void main(String[] arg){
System.out.println("f(5) = " + f(5));
System.out.println("f(3) = " + f(3));
}

public static int f(int i){


try{
return i*i;
} finally {
if ( i == 3)
return 0;
}
}
}

154
Izuzeci

Kako se blok finally izvršava u svakom slučaju, onda će metoda f() vratiti
pravilan rezultat za sve vrednosti argumenta, osim za i = 3, kada će se blok
finally izvršiti i vratiti rezultat nula, bez obzira na originalnu vrednost 9, koja je
izračunata i vraćena u bloku try.

9.3. Objekti klase Throwable

Izuzetak, kao i svaki objekat može da se napravi konstrukcionim elementom


new. Ključna reč throw omogućava da se, u slučaju greške, objekat izuzetka
napravljen sa new baci iz date metode, iako metoda ne vraća taj tip objekta.

if (a == null)
throw new NullPointerException();

Izraz throw zahteva jedan argument Throwable tipa, koji mora da bude
instanca klase koja je potklasa klase Throwable.
Klasa Throwable je bazna klasa za sve Java izuzetke i ima dva public
konstruktora:
 Podrazumevani kontruktor.
 Kontruktor koji prihvata argument tipa String (tu može biti smeštena
informacija o prirodi greške)
Exception objekat koji se prosleđuje catch bloku sadrži informacije o prirodi
problema.
 Poruka koja se inicijalizuje u konstruktoru.
 Zapis o call steku (execution stack) u trenutku kada je izuzetak
kreiran i on sadrži pun naziv svih pozvanih metoda, kao i broj linije u
kojoj se poziv dogodio.
Throwable klasa ima public metode koje omogućavaju pristup zapisu poruka i
steka:
 getMessage() - Vraća sadržaj poruke koja opisuje aktuelni izuzetak
(null za većinu predefinisanih klasa),
 printStackTrace() - Ispis poruka i steka na standardni izlaz,

155
Izuzeci

 fillInStackTrace() - ažurira zapis steka za mesto gde se poziv metode


obavlja. Koristi se kada se ponovo baca izuzetak da bi se ažurirao
zapis steka kada je izuzetak ponovo bačen (korisno kod bacanja
sopstvenih izuzetaka).

9.4. Definisanje izuzetka

Razlog za definisanje nove klase izuzetka može biti mogućnost dobijanja


dodatnih informacija o standardnim izuzetcima, a to se može postići ponovnim
bacanjem objekta definisane klase izuzetka ili mogućnost pojave nepravilnosti
u programu čija posebnost zahteva novu klasu izuzetka. Prilikom definisanja
novog tipa izuzetka treba imati u vidu i činjenicu da takav pristup podrazumeva
trošenje značajnog režijskog vremena.
Klasa izuzetka mora da bude podklasa klase Throwable, ali je najbolje da to
bude podklasa klase Exception. To će nametnuti obavezu da se takvi izuzeci
obrade u metodi, koja može da ih izbaci, ili obavezu deklarisanja metode da
može da izbaci taj izuzetak.

public class DefinisaniIzuzetak extends Exception{


//konstruktori
public DefinisaniIzuzetak() { }
public DefinisaniIzuzetak(String s){
super(s);// poziv konstruktora osnovne klase…
}
}
Nova klasa izuzetka mora minimalno da ima podrazumevani konstruktor i
konstruktor koji kao argument ima objekat klase String. String koji se čuva u
klasi Exception automatski će se inicijalizovati imenom klase izuzetka, a
objekat String koji se prosleđuje kao argument u drugom konstruktoru dodaje
se imenu klase i na taj način se formira poruka koja se čuva u objektu izuzetka.
Objekat definisane klase izuzetka može da se izbaci iskazom throw. Znači,
prvo treba napraviti objekat izuzetka, a zatim pomoću ključne reči throw baciti
izuzetak.

DefinisaniIzuzetak di = new DefinisaniIzuzetak();


throw di;

Ako je potrebno objektu izuzetka proslediti neku poruku, onda se to može


učiniti na sledeći način:

156
Izuzeci

DefinisaniIzuzetak di = new DefinisaniIzuzetak("Poruka");


throw di;

Poziv metode getMessage() koja se nalseđuje iz klase Throwable vratiće


objekat tipa String sa sledećim sadržajem:

" DefinisaniIzuzetak: Poruka"

Klasa MojIzuzetak (primer 9.2.) definiše novu klasu izuzetaka. Ona nasleđuje
klasu Exception i definiše dva konstruktora. Prvi konstruktor je podrazumevani
konstruktor, a drugi konstruktor ima kao argument objekat klase String.

Primer 9.2. MojIzuzetak.java

class MojIzuzetak extends Exception{


public MojIzuzetak(){
super();
}
public MojIzuzetak(String poruka){
super(poruka);
}
}

U klasi PrimerMojIzuzetak (primer 9.3.) definiše se funkcija f(), koja izbacuje


izuzetak tipa MojIzuzetak. U metodi main, kod koji može da izbaci izuzetak, a
to je metoda f(), postavlja se u bloku try. Blok catch hvata izuzetak tipa
MojIzuzetak i obaveštava korisnika o tome.

Primer 9.3. PrimerMojIzuzetak.java

public class PrimerMojIzuzetak{


public void f() throws MojIzuzetak {
System.out.println("Funkcija f() baca objekat
MojIzuzetak");
throw new MojIzuzetak();
}

public static void main(String[] arg){


PrimerMojIzuzetak izuzetak =
new PrimerMojIzuzetak();
try {
izuzetak.f();
} catch (MojIzuzetak i){

157
Izuzeci

System.out.println("Uhvacen je objekat
klase MojIzuzetak");
}
}
}

Klasa PrimerMojIzuzetak1 (primer 9.4.) definiše, pored metode f() i metodu


f1() koja koristi konstruktor sa String argumentom klase MojIzuzetak. Dva
bloka try se koriste za poziv funkcija f() i f1(). Sada se za obaveštavanje
korisnika o prirodi problema koristi nasleđena metoda getMessage().

Primer 9.4. PrimerMojIzuzetak1.java

public class PrimerMojIzuzetak1{


public void f() throws MojIzuzetak {
System.out.println("Funkcija f() baca objekat
MojIzuzetak");
throw new MojIzuzetak();
}

public void f1() throws MojIzuzetak {


System.out.println("Funkcija f1() baca objekat
MojIzuzetak");
throw new MojIzuzetak("Izuzteak nastao u medodi f1");
}

public static void main(String[] arg){


PrimerMojIzuzetak1 izuzetak = new PrimerMojIzuzetak1();
try {
izuzetak.f();
} catch (MojIzuzetak i){
System.out.println(i.getMessage());
}

try {
izuzetak.f1();
} catch (MojIzuzetak i){
System.out.println(i.getMessage());
}
}
}

158
OBJEKTNO ORIJENTISANO
PROGRAMIRANJE

PRAKTIKUM

159
Praktikum

160
Praktikum

OBJEKTNO ORIJENTISANO
PROGRAMIRANJE

Evidencija vežbi

Vežba Datum Potpis


V. 1.
V. 2.
V. 3.
V. 4.
V.5.
V.6.
V.7.
V.8.
V.9.

161
Praktikum

162
Praktikum

Vežba 1. - Java razvojno okruženje

Cilj vežbe:
a) Upoznavanje sa Java razvojnim okruženjem.
b) Upoznavanje sa načinom pisanja, kompajliranjem i izvršavanjem
Java programa.
c) Rad sa editorom Text Pad.

1.1. Instaliranje Java razvojnog alata


Šta su Java aplikacije?

Šta je Java aplet?

Dopuniti sliku.

Za pisanje Java programa potrebno je instalirati Java razvojni alat.


Nabrojati najpoznatije Java razvojne alate:
1. _____________________________________________,
2. _____________________________________________,

163
Praktikum

3. _____________________________________________,
4. _____________________________________________,
5. ______________________________________________...
Java tehnologija je razvijena od strane kompanije
__________________________ pa ćemo razmotriti instalaciju i upotrebu
razvojnog okruženja JDK-a (Java Development Kit). JDK je dostupan,
besplatno, i može se dobiti sa WWW sajta (slika 1.1.):

http://www.oracle.com/technetwork/java/javase/downloads/index.html

JDK je kolekcija programa, zasnovanih na tekstualnom režimu rada, koji


omogućavaju rad sa Java programskim jezikom.
Svaka od JDK opcija pokreće se komandama koje se ukucavaju, kao na
primar:

javac Primer.java

Ova komanda poziva Java kompajler koji treba da prevede izvorni Java
program Primer.java da bi se dobila Primer.class binarna datoteka.
Bajtkod u obliku class datoteke može se izvršiti komandom:

java Primer

Ova komanda pokreće bajtkod interpretator i govori mu da izvrši bajtkod


Primer.class.

1.1.1. Instalacija JDK-a

Java Development Kit je dostupan za sledeće platforme:


 Windows
 Solaris
 Linux
 Mac OS

164
Praktikum

Nakon preuzimanja JDK razvojnog alata sa navedene adrese instalacija


počinje tako što se dva puta klikne na fajl instalacione arhive.

Slika 1.1.

Nakon završetka instalacione procedure potrebno je uneti neke izmene i


podesiti odgovarajuće promenljive sistemskog okruženja. Prvo je potrebno
pronaći katalog u kome se nalazi java.exe datoteka (slika 1.2.).

165
Praktikum

Slika 1.2.
U ovom primeru datoteka java.exe, JDK razvojnog alata verzije 1.3.0_02
nalazi se u katalogu C:\jdk1.3.0_02\bin tako da je potrebno podesiti sistemsku
varijablu Path na sledeći način:
Kliknuti desnim tasterom miša na My computer, pa izabrati karticu Advanced
i kliknuti na dugme Enviroment Variables (sl.1.3.).

Slika 1.3.
Izabrati sistemsku variablu Path, kliknuti na Edit i uneti vrednost:

166
Praktikum

PATH = C:\JDK1.3.0_02\BIN

Slika 1.4.
Nakon završene instalacije, i unetih izmena sistemske varijable Path možemo
proveriti da li je JDK razvojni sistem pravilno instaliran i konfigurisan. To
možemo učiniti ako otkucamo sledeću komandu u MS DOS komandnoj liniji:

java –version
Ako je sve u redu treba da se dobije sledeća poruka (u skladu sa verzijom
JDK-a) (sl.1.5.)

Slika 1.5.

167
Praktikum

Ako se dobije poruka -File not found- sistem ne može da pronađe Java
interpretator tako da je potrebno proveriti da li je varijabla PATH dobro
podešena.

1.1.2. Pisanje i izvršavanje Java programa

Java program možemo napisati koristeći bilo koji tekstualni editor.


Program koji će na ekranu ispisati poruku 'Pozdrav svetu' možemo napisati
koristeći MS DOS editor koji možemo startovati iz komandne linije pomoću
komande:

C:\>edit

Nakon toga u prozoru editora potrebno je ukucati izvorni kod programa


PozdravSvetu.java (slika 1.6.).

Listing 1 : PozdravSvetu.java

class PozdravSvetu {
public static void main(String[] arg){
System.out.println("Pozdrav svetu!!");
}
}

Slika 1.6.
Nakon editovanja izvorne verzije programa potrebno je snimiti ga pod nazivom
PozdravSvetu.java.
Ovde treba primetiti da klasa i datoteka izvornog programa moraju da imaju
isto ime (pri čemu treba praviti razliku između malih i velikih slova).

168
Praktikum

Nakon toga potrebno je izvršiti prevođenje izvornog programa u Java class


datoteku PozdravSvetu.class pomoću komande:

C:\>javac PozdravSvetu.java

Ako je izvorni program pravilno napisan, Java prevodilac će prevesti izvorni


kod i dobiće se Java bajtkod u obliku datoteke koja će se zvati
PozdravSvetu.class.
Ovaj bajtkod se može izvršiti pomoću bajtkod interpretatora pomoću komande:

C:\>java PozdravSvetu

Rezultat ove komande je:

Slika 1.7.

1.1.3. Rad sa editorom Text Pad

Kao što smo već napomenuli izvorni Java program može biti napisan u bilo
kom tekstualnom editoru.
Editor TextPad olakšava pisanje izvornog programa, a prilagođen je i za
kompajliranje i izvršavanje Java programa uz pomoć JDK razvojnog okruženja.
Prethodni Java program napisan pomoću TextPad editora prikazan je na slici
1.8.:

169
Praktikum

Slika 1.8.
Ovako napisan Java program potrebno je snimiti koristeći Save opciju menija
File (slika 1.9.).

Slika 1.9.
Kompajliranje Java programa moguće je izvršiti pomoću opcije Compile Java
menija Tools (slika 1.10.).

170
Praktikum

Slika 1.10.
Izvršavanje Java aplikacije moguće je pomoću opcije Run Java Application
menija Tools (slika 1.10.), a rezultat je prikazan na slici 1.11.

Slika 1.11.

171
172
Vežba 2. - Integrisano razvojno okruženje –
NetBeans

Cilj vežbe
a). Upoznavanje sa integrisanim razvojnim okruženjem NetBeans-om
b). Kreiranje projekta u BetBeans-u
c). Dodavanje novih klasa
d). Pokretanje programa

2.1. Uvod

NetBeans, je integrisano razvojno okruženje za kreiranje aplikacija i apleta


zasnovanih na Java tehnologiji. NetBeans je besplatno modularno okruženje
sa grafičkim korisničkim interfejsom.
Ovo razvojno okruženje moguće je dobiti sa Interneta pomoću adrese
http://netbeans.org/downloads/.
Kada se prvi put startuje NetBeans, na ekranu se pojavljuje nekoliko prozora
kao na slci 2.1.

Slika 2.1.

173
Praktikum

Korisniku su na raspolaganju glavni prozor sa linijom menija i toolbar-om u


gornjem delu prozora, kao i palete Projects, Navigator i Editor. Na dnu se
nalazi panel Output, u kome se vidi rezultat kompajliranja i izvršavanja
programa.
Glavni prozor (slika 2.2.) sadrži sistem padajućih menija i toollbar-ova, kao i
palete sa komponentama koje omogućavaju korisniku razvoj aplikacija i apleta
sa grafičkim korisničkim interfejsom.

Slika 2.2.

Projects (slika 2.3.) obezbeđuje hijerarhijski prikaz paketa, objekata i datoteka


iz razvojnog okruženja

Slika 2.3.

2.2. Pravljenje projekta

Osnovna jedinica rada u NetBeans okruženju jeste projekat. Elementi projekta


su:
 izvorni fajlovi,
 informacija o načinu prevođenja i izvršavanja programa,
 detalji o putanjama, dokumentaciji itd.

174
Praktikum

Sve ove podatke NetBeans smešta u glavni folder projekta. Glavni folder
projekta sadrži podfoldere u kojima grupiše podatke po nekom kriterijumu. Da
bi se omogućilo grupisanje više povazanih projekata na jednom mestu, svi
folderi takvih projekata postavljaju u jedan folder koji se naziva radno mesto
(engl. workplace).
1. Novi projekat se pravi biranjem opcije New Project, menija File

Slika 2.4.

2. Ova opcija otvara dijalog New Project. Potrebno je odabrati kategoriju


i vrstu projekta, a zatim kliknuti na dugme Next (slika 2.5.).

Slika 2.5.

3. Ako izaberemo kategoriju Java, a tip projekta Java Application,


otvariće se dijalog New Java Application. Ovaj prozor služi za
specificiranje imena projekta, kao i lokacije foldera u kome će se
projekat nalaziti. Ako se čekira polje Create Main Class, kreiraće se i
klasa, sa main metodom, čije ime treba navesti u odgovarajuće
tekstualno polje (slika 2.6.).

175
Praktikum

Slika 2.6.

Pritiskom na dugme Finish, završava se formiranje projekta


GeometrijskiObjekti i on se otvara u glavnom prozoru NetBeans-a.
U panelu projekta se prikazuju elementi projekta u ubliku strukture stabla.

2.3. Kreiranje nove klase

Nova klasa se kreira na sledeći način:


1. Izabrati File NewFile (otvara se obrazac New File) (slika 2.7.)

Slika 2.7.

2. Iz liste Categories selektovati Java

176
Praktikum

3. U listi File Type odabrati Java Class


4. Kliknuti na Next
5. U polju Name upisati ime klase (Krug)

Slika 2.8.

6. Klknuti na dugme Finish

Nakon toga dobijamo kostur klase u kome treba da dodamo odgovarajući kod
(slika 2.9.).

Slika 2.9.

Dodajemo kod za klasu Krug (slika 2.10.).

177
Praktikum

Slika 2.10.

Zatim, kreiramo novu klasu KrugPrimer, birajući u listi File Type stavku Java
Main Calss (slika 2.11.).

Slika 2.11.

Dodajemo kod u klasi KrugPrimer:

178
Praktikum

Slika 2.12.

2.4. Kompajliranje i pokretanje programa

Klasu možemo da kompajliramo koristeći opciju Compile File menija Run.


Nakon kompajliranja možemo da startujemo aplikaciju pomoću opcije Run File
menija Run, ili desnim klikom na datoteku KrugPrimer, u paleti projekta i
biranjem opcije Run File.
Rezultati se mogu videti u prozoru Output (slika 2.13.).

Slika 2.13.

179
180
Praktikum

Vežba 3. - Elementi Jave

Cilj vežbe
a). Upoznavanje sa tipovima podataka u Javi
b). Rad sa operatorima
c). Upoznavanje sa osnovnim kontrolnim strukturama
d). Modularizacija programa

Zadatak 1.
Vrednost funkcije y se izračunava na sledeći način:
y = min(x,z) + 10
gde min(x,z) predstavlja funkciju koja upoređuje vrednosti promenljivih x i z i
kao rezultat daje manju vrednost. Napisati program koji, za zadate vrednosti x i
z izračunava vrednost funkcije y.

Listing 3.1. Rešenje Zadatka 1.

class Zadatak1 {
public static void main (String arg[]){
int x = 5;
int z = 8;
int y = min(x,z) + 10;
System.out.println("Vrednost funkcije y je:"+ y);
}
public static int min (int a, int b){
if (a < b){
return a;
} else {
return b;
}
}
}

Zadatak 2.
Vrednost funkcije y se izračunava na sledeći način:
y = (min(x,z) +5)*max(x,z)

181
Praktikum

gede min(x,z) predstavlja funkciju koja upoređuje vrednosti promenljivih x i z i


kao rezultat daje manju vrednost, a max(x,z) predstavlja funkciju koja
upoređuje vrednosti promenljivih x i z i kao rezultat daje veću vrednost.
Napisati program koji, za zadate vrednosti x i z izračunava vrednost funkcije y.

Listing 3.2. Rešenje zadatka 2.

class Zadatak2 {
public static void main (String arg[]){
int x = 5;
int z = 8;

int y = (min(x,z) + 5)*max(x,z);


System.out.println("Vrednost funkcije y:"
+ y);
}

public static int min(int a, int b){


if (a < b){
return a;
} else {
return b;
}
}

public static int max(int c, int d){


if (c > d){
return c;
} else {
return d;
}
}
}

Zadatak 3.
Napisati program koji za zadato n izračunava zbir kvadrata prvih n
nenegativnih celih brojeva.

Listing 3.3. Rešenje zadatka 3.

class Zadatak31 {
public static void main (String arg[]) {

182
Praktikum

int n = 7;
int suma = 0;

for (int i = 1; i <= n; i++){


suma = suma + i*i;
}

System.out.println("Zbir kvadrata prvih " + n +


" nenegativnih celih brojeva je;"+ suma);
}
}

Listing 3.4. Rešenje zadatka 3 – drugi način


import java.io.*;

class Zadatak32 {
public static void main (String arg[]) throws
java.io.IOException{
int n;
int suma = 0;

BufferedReader b;
b = new
BufferedReader(new InputStreamReader(System.in));

System.out.print("Unesi n:");
n = Integer.parseInt(b.readLine());

for (int i = 1; i <= n; i++){


suma = suma + i*i;
}
System.out.println("Zbir kvadrata prvih " + n +
" nenegativnih celih brojeva je;"+ suma);
}
}

Listing 3.5. Rešenje zadatka 3 –treći način

import javax.swing.*;
import javax.swing.event.*;

class Zadatak33 {
public static void main (String arg[]){
int n;
int suma = 0;
String s = JOptionPane.showInputDialog("Unesi n: ");
n = Integer.parseInt(s);
for (int i = 1; i <= n; i++){

183
Praktikum

suma = suma + i*i;


}
System.out.println("Zbir kvadrata prvih " + n +
" nenegativnih celih brojeva je;"+ suma);
}
}

Listing 3.6. Rešenje zadatka 3 – četvrti način

import java.util.*;

class Zadatak34 {
public static void main (String arg {
int n;
int suma = 0;
System.out.print("Unesi n:");
Scanner s = new Scanner(System.in);
n = s.nextInt();
for (int i = 1; i <= n; i++){
suma = suma + i*i;
}
System.out.println("Zbir kvadrata prvih " + n +
" nenegativnih celih brojeva je;"+ suma);
}
}

Zadatak 4.
Izračunati novu cenu proizvoda nakon poskupljenja od 15%. Prvobitna cena se
unosi sa tastature kao neki decimalni broj. Novu cenu treba formatirati pre
prikaza na ekranu.

Listing 3.6. Rešenje zadatka 4

import java.util.*;
import java.text.DecimalFormat;
public class Zadatak4 {
public static void main(String[] args){
double cena = 0;
System.out.println("Unesite cenu pre poskupljenja: ");
Scanner s = new Scanner(System.in);
cena = s.nextDouble();
cena = cena * 1.15;
DecimalFormat formater =

184
Praktikum

new DecimalFormat("###,###.##");
System.out.println("Cena posle poskupljenja od 15%
iznosi: " + formater.format(cena));
}
}

185
186
Praktikum

Vežba 4. - Projektovanje klase Kocka

Cilj vežbe:
a). Definisanje klase
b). Identifikacija polja u klasi prema zadatim uslovima
c). Identifikacija metoda klase prema zadatim uslovima
d). Kreiranje objekata klase i rad sa njima

Projektovati klasu Kocka koja će omogućiti korisniku da zada dimenzije


objekta klase Kocka i da za zadati objekat klese Kocka odredi površinu i
zapreminu.

Rešenje

Korak 1. Identifikacija polja klase Kocka

Klasa Kocka treba da ima sledeća polja:


 visina
 duzina
 sirina
 povrsina
 zapremina

class Kocka{
private int visina;
private int duzina;
private int sirina;
private double povrsina;
private double zapremina;
}

187
Praktikum

Korak 2. Identifikacija metoda klase Kocka


Klasa Kocka treba da sadrži konstruktor koji će definisati početne vrednosti za
polja u trenutku kreiranja objekta klase Kocka.

public Kocka(){
visina = 0;
duzina = 0;
sirina = 0;
}

public Kocka(int visina, int sirina, int duzina){


this.visina = visina;
this.sirina = sirina;
this.duzina = duzina;
}

Klasa Kocka treba da sadrži metode koje će omogućiti postavljanje vrednosti


za prethodno definisana polja. Te metode su:
 postaviVisinu
 postaviDuzinu
 postaviSirinu

public void postaviVisinu(int visina){


this.visina = visina;
}
public void postaviDuzinu(int duzinu){
this.duzina = duzina;
}
public void postaviSirinu(int sirina){
this.sirina = sirina;
}

Metoda koja izračunava površinu kocke:

public void povrsinaKocke(){


povrsina = 2*visina*sirina + 2*sirina*duzina +
2*visina*duzina;
}

188
Praktikum

Metoda koja izračunava zapreminu kocke:

public void zapreminaKocke(){


zapremina = visina*sirina*duzina;
}

Metoda koja prikazuje dimenzije, površinu i zapreminu objekta klase Kocka:

public void prikazi (){


System.out.println("Visina kocke je:" + visina);
System.out.println("Sirina kocke je:" + sirina);
System.out.println("Duzina kocke je:" + duzina);
System.out.println("Povrsina kocke je:" + povrsina);
System.out.println("Zapremina kocke je:" +
zapremina);
}

Kompletan kod klase Kocka dat je u nastavku:

Listing 4.1. - Kocka.java

class Kocka{
private int visina;
private int duzina;
private int sirina;
private double povrsina;
private double zapremina;
public Kocka(){
visina = 0;
duzina = 0;
sirina = 0;
}

public Kocka(int visina, int sirina, int duzina){


this.visina = visina;
this.sirina = sirina;
this.duzina = duzina;
}

public void postaviVisinu(int visina){


this.visina = visina;
}

189
Praktikum

public void postaviDuzinu(int duzinu){


this.duzina = duzina;
}
public void postaviSirinu(int sirina){
this.sirina = sirina;
}
public void povrsinaKocke(){
povrsina = 2*visina*sirina + 2*sirina*duzina +
2*visina*duzina;
}
public void zapreminaKocke(){
zapremina = visina*sirina*duzina;
}
public void prikazi (){
System.out.println("Visina kocke je:" + visina);
System.out.println("Sirina kocke je:" + sirina);
System.out.println("Duzina kocke je:" + duzina);
System.out.println("Povrsina kocke je:" + povrsina);
System.out.println("Zapremina kocke je:" +
zapremina);
}
}

Zadatak

Napisati program u Java programskom jeziku koji će:

- Kreirati novi objekat novaKocka klase Kocka sa dimenzijama 7,5,9


- Izračunati povrsinu objekta novaKocka
- Izračunati zapreminu objekta novaKocka
- Prikazati karakteristike objekta novaKocka
- Promeniti visinu noveKocke na 11
- Promeniti sirinu noveKocke na 3
- Izračunati povrsinu objekta novaKocka
- Izračunati zapreminu objekta novaKocka
- Prikazati karakteristike objekta novaKocka

190
Praktikum

Rešenje

Listing 4.2. - PrimerSaKockom.java

class PrimerSaKockom{
public static void main(String[] arg){
Kocka novaKocka = new Kocka(7,5,9);
novaKocka.povrsinaKocke();
novaKocka.zapreminaKocke();
novaKocka.prikazi ();
novaKocka.postaviVisinu(11);
novaKocka.postaviSirinu(3);
novaKocka.povrsinaKocke();
novaKocka.zapreminaKocke();
System.out.println("Nove dimenziije su:");
novaKocka.prikazi();
}
}

191
Praktikum

192
Vežba 5. - Objekat Niz i String

Cilj vežbe:

a) Ova vežba nas upoznaje sa nizovima u Java programskom jeziku


Niz predstavlja skup podataka istog tipa sa zajedničkim imenom. U Java
programskom jeziku nizovi se implementiraju kao objekti. Da bi se kreirao niz u
Javi potrebno je uraditi sledeće:
 Deklarisati promenljivu u kojoj će se čuvati niz
 Kreirati novi objekat niza i dodeliti mu deklarisanu promenljivu
 Smestiti podatke u niz.
Deklaracija promenljive u kojoj će se čuvati niz vrši se na sličan način kao i
deklaracija obične promenljive samo što se deklaraciji niza dodaje par srednjih
zagrada '[' i ']', kao na primer:
int x[];
Nakon deklarisanja promenljive koja će čuvati niz, potrebno je kreirati objekat
niza. To se može uraditi pomoću operatora new na sledeći način:
x = new int[10];
Svakom članu niza možemo pristupiti navođenjem odgovarajućeg indeksa
između uglastih zagrada.
x[0] = 5;
x[1] = 7;
...
 Definisaćemo klasu Niz koja će imati jedno polje x, u kome ćemo
čuvati elemente niza.

public class Niz{


int x[];
. . .
// Kraj klase
}

 Konstruktor pravi novi objekat klase Niz sa datim brojem elemenata.

193
Praktikum

// Konstruktor
public Niz(int brojElemenata){
x=new int[brojElemenata];
}

 Metoda generisiSlucajanNiz generiše elemente niza čije su vrednosti


slučajne veličine u opsegu od 0 do 100.

// Generisanje niza ciji su clanovi slucajni


public int[] generisiSlucajanNiz() {
for (int i=0; i<x.length; i++)
x[i]=(int)(Math.random()*100);
return x;
}

 Metoda stampajNiz prikazuje članove niza.

// Stampanje clanova niza


public void stampajNiz() {
for (int i = 0; i<x.length; i++)
System.out.println("x["+i+"] = " + x[i]);
}

 Metoda nadjiMaksimalanClan nalazi clan niza čija je vrednost


maksimalna.

// Maksimalan clan niza


public int nadjiMaksimalanClan(){
int max=x[0];
for (int i=0; i<x.length; i++) {
if(x[i]>max)
max=x[i];
}
return max;
}

194
Praktikum

 Metoda nadjiMinimalanClan nalazi clan niza čija je vrednost


minimalna.

// Minimalan clan niza


public int nadjiMinimalanClan(){
int min=x[0];
for (int i=0; i<x.length; i++) {
if(x[i]<min)
min=x[i];
}
return min;
}

 Metode sortirajNizMI i sortirajNizMJZ sortiraju članove niza


metodom izbora i metodom jednostruke zamene.

// Sortiranje niza metodom izbora


public void sortirajNizMI(){
for (int i=0; i<x.length-1; i++) {
for (int j=i+1; j<x.length; j++) {
if (x[i] > x[j]) {
promeni(i, j);
}
}
}
}

// Sortiranje niza metodom jednostruke zamene


public void sortirajNizMJZ(){
int l=x.length-1;
int kon;
do {
kon=0;
for(int i=0; i<l; i++){
if (x[i] > x[i+1]) {
promeni(i, i+1);
}
kon=1;
}
l=l-1;
} while(l*kon!=0);
}

195
Praktikum

 Metoda Promeni je pomoćna metoda koja izmenjuje vrednosti


odgovarajućih članova niza.

public void promeni(int i, int j){


int temp = x[i];
x[i] = x[j];
x[j] = temp;
}

Kompletan kod klase Niz.java je dat u nastavku.

Listing 5.1. - Niz.java

public class Niz{


int x[];
// Konstruktor
public Niz(int brojElemenata){
x=new int[brojElemenata];
}

// Generisanje niza ciji su clanovi slucajni


public int[] generisiSlucajanNiz() {
for (int i=0; i<x.length; i++)
x[i]=(int)(Math.random()*100);
return x;
}

// Stampanje clanova niza


public void stampajNiz() {
for (int i = 0; i<x.length; i++)
System.out.println("x["+i+"] = " + x[i]);
}

// Maksimalan clan niza


public int nadjiMaksimalanClan(){
int max=x[0];
for (int i=0; i<x.length; i++) {
if(x[i]>max)
max=x[i];
}
return max;
}

// Minimalan clan niza


public int nadjiMinimalanClan(){
int min=x[0];
for (int i=0; i<x.length; i++) {
if(x[i]<min)

196
Praktikum

min=x[i];
}
return min;
}

// Sortiranje niza metodom izbora


public void sortirajNizMI(){
for (int i=0; i<x.length-1; i++) {
for (int j=i+1; j<x.length; j++) {
if (x[i] > x[j]) {
promeni(i, j);
}
}
}
}

// Sortiranje niza metodom jednostruke zamene


public void sortirajNizMJZ(){
int l=x.length-1;
int kon;
do {
kon=0;
for(int i=0; i<l; i++){
if (x[i] > x[i+1]) {
promeni(i, i+1);
}
kon=1;
}
l=l-1;
} while(l*kon!=0);
}

// metoda promeni()
public void promeni(int i, int j){
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}

Zadatak 1:
Koristeći klasu Niz napisati program u Java programskom jeziku koji će:
 Kreirati objekat klase Niz sa 9 elemenata
 Generisati slučajne vrednosti za elemente niza
 Prikazati vrednosti elemenata niza

197
Praktikum

 Sortirati niz
 Prikazati vrednosti elemenata niza
 Naći i prikazati maksimalan elemenat niza.

Rešenje
Listing 5.2. - PrimerSaNizom.java

class PrimerSaNizom{
public static void main(String[] arg){
Niz x=new Niz(9);
x.generisiSlucajanNiz();
x.stampajNiz();
System.out.println("Sortiran niz je:");
x.sortirajNizMI();
x.stampajNiz();
int max=x.nadjiMaksimalanClan();
System.out.println("Maksimalan clan niza je: "
+ max);
}
}

Stek

Stek je memorijska struktura koja je rezervisana za smeštanje podataka koji se


mogu opisati sledećim nizom:
S[1], S[2], S[3],...,S[SP]
Karakteristika steka je da na njega ukazuje vrednost sadržaja registra SP i da
na stek mogu da se smeštaju podaci kao i da se čitaju, ali redosledom
obrnutim od upisivanja podataka.
Za smeštanje podatka na vrh steka definiše se operacija PUSH, a za čitanje
podatka sa vrha steka definiše se operacija POP.
 Projektovaćemo klasu Stek koja će služiti za smeštanje i čitanje
celobrojnih podataka u niz elementi koji sadrži celobrojne podatke.
Celobrojna promenljiva velicina je pokazivač na tekući elemenat
steka.

198
Praktikum

public class Stek {


private int[] elementi;
private int velicina= 0;
//. . .
}

 Konstruktor pravi niz elementi koji ima 100 članova

// konstruktor
public Stek() {
this.elementi = new int[100];
}

 Celobrojne vrednosti se unose na stek i sa steka skidaju pomoću


operacija push i pop. Operacija punjenja steka push

// punjenje steka
public void push(int e) {
elementi[velicina++] = e;
}

 Operacija pražnjenja steka

// praznjenje steka
public int pop() {
int rezultat= elementi[--velicina];
elementi[velicina] = 0;
return rezultat;
}

 Definisaćemo i bezadresne operacije sabiranja i množenja, koje


sabiraju odnosno množe dve vršne vrednosti na steku i rezultat
smeštaju na vrhu steka. Operacija sabiranja add

// operacija sabiranja
public void add() {

199
Praktikum

int zbir = elementi[velicina-1] +


elementi[velicina-2];
velicina=velicina-1;
elementi[velicina] = 0;
elementi[velicina-1] = zbir;
}

 Operacija množenja mull

// operacija množenja
public void mull() {
int zbir = elementi[velicina-1] *
elementi[velicina-2];
velicina=velicina-1;
elementi[velicina] = 0;
elementi[velicina-1] = zbir;
}

Kompletan kod klase Stek je dat u nastavku:

Listing 5.3. - Stek.java

public class Stek {


private int[] elementi;
private int velicina= 0;

// konstruktor
public Stek() {
this.elementi = new int[100];
}

// punjenje steka
public void push(int e) {
elementi[velicina++] = e;
}

// praznjenje steka
public int pop() {
int rezultat= elementi[--velicina];
elementi[velicina] = 0;
return rezultat;
}

// operacija sabiranja
public void add() {
int zbir = elementi[velicina-1] +
elementi[velicina-2];

200
Praktikum

velicina=velicina-1;
elementi[velicina] = 0;
elementi[velicina-1] = zbir;
}

// operacija množenja
public void mull() {
int zbir = elementi[velicina-1] *
elementi[velicina-2];
velicina=velicina-1;
elementi[velicina] = 0;
elementi[velicina-1] = zbir;
}
}

Zadatak 2:
Koristeći klasu Stek Napisati program u Java programskom jeziku koji će:
 Kreirati novi objekat klase Stek.
 Izračunari izraz W = (X+Y)*Z za X = 3, Y = 5, Z = 2.
 Prikazati vrednost promenljive W na ekranu.

Rešenje
Listing 5.4. - PrimerSaStekom.java

public class PrimerSaStekom {


public static void main(String[] arg) {
int x = 3;
int y = 5;
int z = 2;
int w;
Stek s = new Stek();
s.push(x);
s.push(y);
s.add();
s.push(z);
s.mull();
w = s.pop();
System.out.println("W = " + w);
}
}

201
Praktikum

String

Zadatak 3
Napisati program koji učitava tekst sa tastature i formira jedan String (npr.
source). Program zatim kreira jos dva Stringa:
1) string1 se dobija eliminisanjem svih karaktera koji nisu cifre iz
stringa source,
2) string2 se dobija zamenom svih parnih cifara stringa source
njihovim nazivima ispisanih između para uglastih zagrada (npr. 2 -
<dva>, 4 - <cetiri> itd.).
Sva tri stringa ispisati na ekranu jedan ispod drugog.
Rešenje

Listing 5.5. - Zadatak3.java


import java.util.*;

public class Zadatak3 {


static String source = null;
static String string1 = null;
static String string2 = null;
static StringBuffer temp = new StringBuffer();

public static void main(String[] args) {


// preuzimanje source Stringa sa ulaza
System.out.print("Unesi znakovni niz:");
Scanner scan = new Scanner(System.in);
source = scan.next();
// izracunava string 1
for (int i = 0; i < source.length(); i++) {
if (Character.isDigit(source.charAt(i))) {
temp.append(source.charAt(i));
}
}
string1 = temp.toString();
// metod delete prazni StringBuffer za kasniju upotrebu
temp.delete(0, string1.length());

// izracunava string 2
for (int i = 0; i < string1.length(); i++) {
char k = string1.charAt(i);

// ako je broj paran


if (((int)k % 2) == 0) {
// zameni sve parne cifre zeljenim stringom
switch (k) {

202
Praktikum

case '0':
temp.append("<nula>");
break;
case '2':
temp.append("<dva>");
break;
case '4':
temp.append("<cetiri>");
break;
case '6':
temp.append("<sest>");
break;
case '8':
temp.append("<osam>");
break;
}
}
}
string2 = temp.toString();
// ispisivanje rezultata
System.out.println("source: " + source);
System.out.println("string1: " + string1);
System.out.println("string2: " + string2);
}
}

Zadatak 4
Napisati program koji prima jedan String koji se sastoji od vše brojeva
odvojenih zarezom (npr., "456,32,44,31,5"), izracunava zbir tih brojeva
(456+32+44+31+5).

Listing5.6. - Zadatak4.java

class Zadatak4 {
public static void main(String arg[]){
int zbir = 0;
String nizBrojeva = "123,56,23,89,33";
String[] brojevi = nizBrojeva.split(",");

for ( int i = 0; i < brojevi.length; i++ ) {


int broj = Integer.parseInt( brojevi[i] );
zbir += broj;
}

System.out.println("Zbir je:"+ zbir);


}
}

203
Praktikum

204
Vežba 6. - Projektovanje klase Student

Cilj vežbe:
a). Definisanje klase
b). Identifikacija polja u klasi prema zadatim uslovima
c). Identifikacija metoda klase prema zadatim uslovima
d). Preklapanje metoda
e). Kreiranje objekata klase i rad sa njima

Projektovati klasu Student koja će omogućiti identifikaciju studenta pomoću


imena, prezimena i broja indeksa kao i odseka na kom student studira. Takođe,
svaki objekat klase Student treba da sadrži i listu položenih ispita. Korisniku
treba omogućiti da prikaže listu svih položenih ispita ili da prikaže ostvarene
rezultate studenta za zadati predmet.

Korak 1. Identifikacija polja klase Student


Klasa Student treba da ima sledeća polja:
 ime: String
 prezime: String
 brIndeksa: String
 odsek: String
Da bi smo definisali listu položenih ispita možemo da definišemo dva niza. U
jednom (ispiti) čuvaćemo nazive ispita, a u drugom (ocene) čuvaćemo ocene.
Svaki ispit povezan je sa ocenom pomoću odgovarajućeg indeksa niza, koga
čemo čuvati u statičkoj promenljivoj indeksNiza.
 ispiti (niz koji sadrži ispite)
 ocene (niz koji sadrži ocene)

Listing 6.1.

class Student{
String ime;
String prezime;
String brIndeksa;
String odsek;
String[] ispiti;

205
Praktikum

int[] ocene;
static int indeksNiza = 0;
...
}

Korak 2. Identifikacija metoda klase Student


Klasa Student treba da sadrži konstruktor koji će inicijalozovati objekat klase
Student.

Student(){
ispiti = new String[10];
ocene = new int[10];
}

Klasa Student treba da sadrži metode koje će omogućiti postavljanje vrednosti


za prethodno definisana polja. Te metode su:
 postaviIme(ime:String)
 postaviPrezime(prezime:String)
 postaviIndeks(brIndeksa:String)
 postaviOdsek(odsek:String)

Listing 3.3.
public void postaviIme(String ime){
this.ime = ime;
}
public void postaviPrezime(String prezime){
this.prezime = prezime;
}
public void postaviIndeks(String indeks){
this.brIndeksa = indeks;
}
public void postaviOdsek(String odsek){
this.odsek = odsek;
}

206
Praktikum

Metoda polozioIspit omogućava unos naziva predmeta i ocene koju je student


ostvario polaganjem tog predmeta.
 polozioIspit(ispit:String, ocena:int)

public void polozioIspit(String ispit, int ocena){


for (int i = 0; i< ispiti.length; i++){
if (ispiti[i]==null){
this.ispiti[indeksNiza] = ispit;
this.ocene[indeksNiza++] = ocena;
break;
}
}
}

Korak 3. Definisanje metode prikazi(), koja će prikazati listu položenih ispita i


njeno preklapanje metodom koja će omogućiti prikaz ocene za zadati predmet.

public void prikazi(){


System.out.println("---------------------------");
System.out.println("Ime: "+ime);
System.out.println("Prezime: "+prezime);
System.out.println("Broj indeksa: " + brIndeksa);
System.out.println("Studijski program: " + odsek);
System.out.println("Student je polozio
sledece ispite");
for (int i = 0; i< ispiti.length; i++){
if (ispiti[i]!=null)
System.out.println(""+ispiti[i]+"-----"
+ ocene[i]);
}
System.out.println("----------------------------");
}

Preklopljena metoda prikazi()

public void prikazi(String ispit){


System.out.println("----------------------------");
System.out.println("Ime: "+ime);
System.out.println("Prezime: "+prezime);
System.out.println("Broj indeksa: "+brIndeksa);
System.out.println("Studijski program: "+odsek);
for (int i = 0; i< ispiti.length; i++){

207
Praktikum

if (ispiti[i]!=null && ispiti[i].equals(ispit))


System.out.println("Na ispitu " + ispiti[i] +
" student " + ime + " " + prezime + " je

ostvario ocenu "+ocene[i]);


}
System.out.println("----------------------------");
}

Kompletan kod klase Student dat je u nastavku:


Listing 6.1. - Student.java

public class Student {


String ime;
String prezime;
String brIndeksa;
String odsek;
String[] ispiti;
int[] ocene;
static int indeksNiza = 0;
Student(){
ispiti = new String[10];
ocene = new int[10];
}

public void postaviIme(String ime){


this.ime = ime;
}
public void postaviPrezime(String prezime){
this.prezime = prezime;
}
public void postaviIndeks(String indeks){
this.brIndeksa = indeks;
}
public void postaviOdsek(String odsek){
this.odsek = odsek;
}
public void polozioIspit(String ispit, int ocena){
for (int i = 0; i< ispiti.length; i++){
if (ispiti[i]==null){
this.ispiti[indeksNiza] = ispit;
this.ocene[indeksNiza++] = ocena;
break;
}
}
}

public void prikazi(){


System.out.println("---------------------------");
System.out.println("Ime: "+ime);

208
Praktikum

System.out.println("Prezime: "+prezime);
System.out.println("Broj indeksa: " + brIndeksa);
System.out.println("Studijski program: " + odsek);
System.out.println("Student je polozio sledece ispite");
for (int i = 0; i< ispiti.length; i++){
if (ispiti[i]!=null)
System.out.println(""+ispiti[i]+"-----" +
ocene[i]);
}
System.out.println("----------------------------");
}

public void prikazi(String ispit){


System.out.println("----------------------------");
System.out.println("Ime: "+ime);
System.out.println("Prezime: "+prezime);
System.out.println("Broj indeksa: "+brIndeksa);
System.out.println("Studijski program: "+odsek);
for (int i = 0; i< ispiti.length; i++){
if (ispiti[i]!=null && ispiti[i].equals(ispit))
System.out.println("Na ispitu " + ispiti[i] + "
student " +
ime + " " + prezime + " je ostvario ocenu
"+ocene[i]);
}
System.out.println("----------------------------");
}
}

Zadatak
Napisati program u Java programskom jeziku koji će:
 Kreirati nove objekat pera klase Student
 Objekat pera treba da ima sledeće karakteristike
 ime: Petar
 prezime:Petrovic
 broj indeksa: 377/89
 odesek: poslovna informatika
 Student pera položio je sledeće ispite:
 Matematika 7
 Sociologija 8
 Informatika 9
 prikazati karakteristike objekta pera
 Prikazati ocenu za predmet "Sociologija"

209
Praktikum

Listing 6.2. - PrimerStudent.java

class PrimerStudent {
public static void main(String arg[]){
Student pera;
pera = new Student();
pera.postaviIme("Petar");
pera.postaviPrezime("Petrovic");
pera.postaviIndeks("377/89");
pera.postaviOdsek("Poslovna informatika");
pera.polozioIspit("Matematika", 7);
pera.polozioIspit("Sociologija", 8);
pera.polozioIspit("Informatika", 8);
pera.prikazi();
pera.prikazi("Sociologija");

}
}

210
Vežba 7. – Klasa Banka

Zadatak

Klasa Banka ima metodu otvoriRacun() koja otvara novi račun i ubacuje ime
komintenta i broj računa u bazu podataka, metodu povecajUlog () koja
povecava zadati ulog za zadati broj računa i metodu prikaziStanje () koja
prikazuje stanje na datom računu.

Polja klase Banka

class Banka{
public final int BROJ = 100;
String[] komintent;
int[] brojRacuna;
int[][] iznos;

int broj = 0;
int broj1 = 0;
}

Konstruktor klase Banka

public Banka(){
komintent = new String[BROJ];
brojRacuna = new int[BROJ];
iznos = new int[BROJ][2];
}

Metoda otvoriracun()

public void otvoriRacun(){


komintent[broj] =
JOptionPane.showInputDialog("Unesi naziv komintenta: " );
brojRacuna[broj] =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi broj racuna: " ));

211
Praktikum

broj++;
}

Metoda povecajUlog()

public void povecajUlog(){


int brRacuna =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi broj racuna za unos uloga: " ));
int iznos1 =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi iznos: " ));
iznos[broj1][0] = brRacuna;
iznos[broj1][1] = iznos1;
broj1++;
}

Metoda prikaziStanje()

public void prikaziStanje(){


int brRacuna =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi broj racuna za prikaz stanja: " ));

String ime = "";


for (int i = 0; i < broj; i++){
if (brRacuna == brojRacuna[i])
ime = komintent[i];
}

String sadrzaj = "";


for (int i = 0; i < broj1; i++){
if (brRacuna == iznos[i][0])
sadrzaj = sadrzaj + iznos[i][0] +
" "+ iznos[i][1] + " \n";
}

JOptionPane.showMessageDialog(null,
"Broj racuna Iznos \n\n" +
sadrzaj, "ime:" + ime,JOptionPane.PLAIN_MESSAGE );
}

212
Praktikum

Kompletan kod klase Banka dat je u nastaku:

Listing 7.1. - Banka.java

class Banka{
public final int BROJ = 100;
String[] komintent;
int[] brojRacuna;
int[][] iznos;

int broj = 0;
int broj1 = 0;

public Banka(){
komintent = new String[BROJ];
brojRacuna = new int[BROJ];
iznos = new int[BROJ][2];
}

public void otvoriRacun(){


komintent[broj] =
JOptionPane.showInputDialog("Unesi naziv komintenta:");
brojRacuna[broj] =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi broj racuna: " ));
broj++;
}

public void povecajUlog(){


int brRacuna =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi broj racuna za unos uloga: " ));
int iznos1 =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi iznos: " ));
iznos[broj1][0] = brRacuna;
iznos[broj1][1] = iznos1;
broj1++;
}

public void prikaziStanje(){


int brRacuna =
Integer.parseInt(JOptionPane.showInputDialog(
"Unesi broj racuna za prikaz stanja: " ));

String ime = "";


for (int i = 0; i < broj; i++){
if (brRacuna == brojRacuna[i])
ime = komintent[i];
}

String sadrzaj = "";


for (int i = 0; i < broj1; i++){

213
Praktikum

if (brRacuna == iznos[i][0])
sadrzaj = sadrzaj + iznos[i][0] +
" "+ iznos[i][1] + " \n";
}

JOptionPane.showMessageDialog(null,
"Broj racuna Iznos \n\n" +
sadrzaj, "ime:" + ime,JOptionPane.PLAIN_MESSAGE );
}
}

Zadatak:

Napisati program na Java programskom jeziku koji će:


 napraviti novi objekat b klase Banka
 ubaciti nove komintente prema tabeli

Ime Broj racuna


Pera 55
Laza 56
Mika 57

 Povećati uloge na racunima prema tabeli

Broj racuna Količina


55 100
55 50
56 200
56 50
57 100
57 150
57 200

 prikazati stanje na Mikinom racunu

214
Praktikum

Rešenje

Listing 7.2. - BankaPrimer.java

class BankaPrimer{
public static void main (String[] arg){
Banka b = new Banka();
b.otvoriRacun();
b.otvoriRacun();
b.otvoriRacun();

b.povecajUlog();
b.povecajUlog();
b.povecajUlog();
b.povecajUlog();
b.povecajUlog();
b.povecajUlog();
b.povecajUlog();
b.prikaziStanje();
}
}

215
216
Lab. vežba 8. - Nasleđivanje i polimorfizam

Cilj vežbe:
a) Upoznavanje i definisanje apstraktne klase
b) Upoznavanje sa nasleđivanjem klasa
c) Upoznavanje sa polimorfizmom
d) Upotreba redefinisanja metoda

Zadatak

(1) Napraviti apstraktnu klasu Zaposleni koja ima:


 Svojstva ime i prezime
 Svojstvo plata koji je realan broj.
 Metodu getPlata koja vraća trenutnu vrednost atributa plata.
 Apstraktnu metodu izracunajPlatu koja ne vraća ništa, ali ima ulazni
argument koji predstavlja broj sati koji je zaposleni radio.
 Redefinisati metodu equals klase Object tako da se dva zaposlena
smatraju jednakim ako imaju istu platu
(2) Napraviti klasu KancelarijskiRadnik koja nasleđuje klasu Zaposleni i:
 Realizuje metodu izracunajPlatu. Ova metoda postavlja vrednost
atributa plata prema formuli PLATA = 100 * BROJ_SATI.
(3) Napraviti klasu Menadzer koja nasleđuje klasu Zaposleni i:
 Realizuje metodu izracunajPlatu. Ova metoda postavlja vrednost
atributa plata prema formuli PLATA = 200 * BROJ_SATI.

Listing 5.1. - Klasa Zaposleni.java

public abstract class Zaposleni {


String ime;
String prezime;
double plata;

public Zaposleni(String ime, String prezime){


this.ime = ime;
this.prezime = prezime;
}

public String getIme(){


return ime;
}

217
Praktikum

public String getPrezime(){


return prezime;
}

public double getPlata() {


return plata;
}

public boolean equals(Object o) {

Zaposleni p = (Zaposleni)o;
if ( p.getPlata() == this.getPlata() )
return true;
else
return false;
}

public abstract void izracunajPlatu (int broj_sati);

Listing 5.2. Klasa KancelarijskiRadnik.java

public class KancelarijskiRadnik extends Zaposleni {

public KancelarijskiRadnik(String ime, String prezime){


super(ime,prezime);
}

public void izracunajPlatu(int broj_sati) {


plata = 100 * broj_sati;
}
}

Listing 5.3. Klasa Menadzer.java


public class Menadzer extends Zaposleni {
public Menadzer(String ime, String prezime){
super(ime,prezime);
}
public void izracunajPlatu(int broj_sati) {
plata = 200 * broj_sati;
}
}

218
Praktikum

Zadatak
Napraviti klasu PrimerZaposleni i kreirati dva objekta klase
KancelarijskiRadnik i jedan objekat klase Menadzer i smestiti sve ove objekte
u niz čiji su elementi objekti klase Zaposleni. Izracunati i ispisati plate svih
radnika, ako se zna da je Menadzer radio 200 sati, a kancelarijski radnici 200
odnosno 400 sati.

Listing 5.4. PrimerZaposleni.java

public class PrimerZaposleni {

public static void main(String[] args) {

Zaposleni[] z = new Zaposleni[3];

KancelarijskiRadnik k1 =
new KancelarijskiRadnik("Petar", "Petrovic");
KancelarijskiRadnik k2 =
new KancelarijskiRadnik("Mile", "Milic");
Menadzer m = new Menadzer("Micko", "Mickic");

k1.izracunajPlatu(200);
k2.izracunajPlatu(400);
m.izracunajPlatu(200);

z[0] = k1;
z[1] = k2;
z[2] = m;

for (int i = 0; i < z.length; i++){


System.out.println("Plata zaposlenog " +
z[i].getIme() +" "+ z[i].getPrezime()+
" je " + z[i].getPlata());
}

if (k2.equals(m)){
System.out.println("Zaposleni "+ m.getIme() +
" i zaposleni " + k2.getIme() +
" imaju iste plate");
} else {
System.out.println("Zaposleni "+ m.getIme() +
" i zaposleni " + k2.getIme() +
" nemaju iste plate");
}
}
}

219
Lab. vežba 9. - Pravljenje grafičkog
korisničkog interfejsa u NetBeans-u

Izgradnja aplikacija i apleta sa grafičkim korisničkim interfejsom prevazilazi


okvire ovog kursa, ali ćemo samo ilustrativno pokazati kako je moguće pomoću
NetBeans razvojnog okruženja napraviti jednostavan program sa grafičkim
korisničkim interfejsom.
Napravićemo jedan prozor gde ćemo moći da unesemo vrednost za poluprečik
kruga, i da dobijemo vrednost površine kruga u drugom polju, pritiskom na
dugme Izracunaj.
1. Kreirati projekat
2. Izabrati File New (otvara se obrazac New)
3. Izabrati kategoriju Swing GUI forms
4. Izabrati iz liste File Types stavku JFrame Form

Slika 9.1.

5. U polju Name uneti KrugFrame


6. Pritisnuti digme Finish

Dobićemo novi prozor (slika 9.2.) kome treba da podesimo određene


karakteristike.

221
Slika 9.2.
Karakteristike možemo da podesimo ako desnim tasterom miša kliknemo na
prozor.
Način prikazaivanja komponenata na prozoru određen je opcijom Set Layout
(slika 9.3.).

Slika 9.3

Izabraćemo opciju FlowLayout .


Raspoređivač FlowLayout raspoređuje komponente počev od gornjeg levog
ugla, s leva na desno, odozgo nadole.
Zatim ćemo dodati na prozor komponente ovim redom: Label, Label,
TextField, TextField, Button. Komponente se biraju u paleti, koja se nalazi sa
desne strane glavnog prozora, i prevlače se na prozor, koji je kreiran u
centralnom delu.

222
Slika 9.4.

Zatim se vrši podešavanje komponenti.


Komponente, kao i svi objekti imaju osobine i ponašanja, koje se mogu podesiti
u paleti Properties.
Za labele, potrebno je izmeniti svojstvo "text". Za prvu labelu vrednost "text"
trba da bude "Poluprecnik kruga:", a za drugu "Povrsina:".
Zatim treba pronaći svojstvo text u prozoru Properties za jTextField1,
jTextField2 i izbrisati ga.
Na slican nacin treba promeniti svojstvo Variable Name komponente
jTextField1 i jTextField2. To se može uraditi tako što se klijne desnim
tasterom miša na tekstualno polje, izabere se Properties, pa Variable Name i
unese se poluprecnikText, za jedno i povrsinaText, za drugo polje.
Kliknuti desnim tasterom miša na dugme i izabrati Properties. Pronaći svojstvo
label i upisati Izracunaj.
Nakon toga prozor izgleda kao na slici.

Slika 9.5.

223
Sada je potrebno podesiti svojstva dugmeta i definisati šta će da se desi kada
se mišem klikne na njega.
Kliknuti desnim tasterom miša na dugme, izabrati Events, Mouse i klknuti
mišem na MouseClicked.
U odgovarajućoj datoteci biće dodata metoda:

private void izracunajMouseClicked(java.awt.event.MouseEvent evt)

gde treba uneti odgovarajući kod :

private void izracunajMouseClicked(java.awt.event.MouseEvent evt)


{
// TODO add your handling code here:
int r = Integer.parseInt(poluprecnikText.getText());
double povrsina = r*r*3.14;
povrsinaText.setText("" + povrsina);
}

Grafička komponenta polje za unos teksta (TextField) ima metodu setText


koja određuje tekst koji će biti upisan u polje za tekst, i metodu getText koja
očitava sadržaj polja za tekst.
Metoda getText vraća znakovni niz pa je ovde potrebno konverovati znakovni
niz u celobrojnu vrednost, pošto je potrebno sabrati sadržaje dva polja. To se
postiže upotrebom metode parseInt klase Integer.
Metoda setText treba da ima jedan argument tipa znakovni niz, tako da je
potrebno konvertovati dobijeni zbir, koji je celobrojnog tipa, u znakovni niz. To
se može postići automatski ako zbiru dodamo prazan znakovni niz (“ ”) na
početku.

Slika 9.6.

224
Sada možemo da izvršimo program (Run Run file). U polje poluprecnik
treba uneti odgovarajuću vrednost i klikom na dugme Izracunaj dobijamo
rezultat (slika 9.7).

Slika 9.7.

225
Literatura

[1] C.S.Horstman, G.Cornell, Java 2, tom I, CET, 2008, Beograd


[2] C.S.Horstman, G.Cornell, Java 2, tom II, CET, 2008, Beograd
[3] J.Bloch, Effective Java, Sun, 2008.
[4] I.Horton, Java 2 JDK 5, prva knjiga, CET, 2006, Beograd
[5] I.Horton, Java 2 JDK 5, druga knjiga, CET, 2006, Beograd
[6] I.Craig, The Interpretation of Object-Orinted Programing
Languages, Springer, 2002.
[7] K. Arnold, J. Gosling, D. Holmes, Programski jezik JAVA, CET, 2001.
[8] H. M. Deitel, P.J. Deitel, S.E. Santry, Advanced Java 2 Platform,
Prentice Hall. 2002
[9] H. Schildt, Java 2, Mikro Knjiga, 2001
[10] L G. Booch, J.Rumbaugh, I. Jacobson, UML vodič za korisnike, CET,
2001, Beograd.
[11] B. Eckel, Thinking in Java, Prentice Hall, 2000
[12] G. Seshadri, Enterprise Java Computing - Aplication and
Architecture, Cambridge University Press,1999
[13] Dujmović J., Programski jezici i metode programiranja, Naučna
knjiga, Beograd, 1990
[14] Lemay, R. Codenhead, Java 1.2 naučite za 21 dan, Kompjuter
biblioteka, 1998, Čačak
[15] D. Milićev, Objektno orijentisano programiranje na jeziku C++,
Mikro knjiga, 1995
[16] D. Champeaux, D. Lee, P. Faure, Object-Oriented System
Development, Addison Wesley, 1993
[17] http://docs.oracle.com/javase/tutorial/

You might also like