Documente Academic
Documente Profesional
Documente Cultură
U Javi se može prilikom stvaranja nove klase daklarirati da je nova klasa podklasa
postojeće klase. U slučaju klase B koja se definira kao podklasa klase A to se
zapisuje ovako:
class B extends A {
.
. // dodaci na, i izmijene
. // onog što je naslijeđeno od klase A
.
}
ili čak:
Vehicle myVehicle = new Car();
Nakon bilo kojeg od ovih izraza varijabla myVehicle sadrži poziv na Vehicle objekt
koji je instanca podklase Car. Objekt "pamti" da je zapravo Car, a ne samo Vehicle.
Podatak o stvarnoj klasi objekta je spremljen kao dio tog objekta. Čak je moguće
ispitati pripada li objekt danoj klasi koristeći instanceof operator:
if (myVehicle instanceof Car) ...
nije dozvoljen jer myVehicle može pokazivati na druge tipove iz klase Vehiclea a ne
samo iz klase Car. Slično kao kad računalo ne dozvoljava
pridjeljivanje int vrijednosti short varijabli, jer svaki int nije nužno i short. Rješenje
ovog slučaja je opet pretvaranje tipova. Ako slučajno znamo da se myVehicle uistinu
odnosi na Car, možemo pretvoriti tip izrazom:
myCar = (Car)myVehicle;
Za još jedan primjer, razmotrimo program koji radi s oblicima prikazanim na slici:
pravokutnicima (Rectangle), elipsama (Oval) i zaobljenim pravokutnicima
(Rounded Rectangle) raznih boja.
Klase Rectangle, Oval, i RoundRect predstavljaju tri vrste oblika. Ove tri klase imaju
zajedničku nadklasu Shape koja predstavlja zajedničke osobine svih triju
elemenata. Klasa Shape može sadržavati varijable instance koje predstavljaju boju,
položaj i veličinu oblika. Osim toga može sadržavati metode instance za mijenjanje
boje, položaja i veličine oblika. Radnja poput promjene boje sastoji se od promjene
varijable instance i ponovnog iscrtavanja oblika u novoj boji:
class Shape {
void redraw() {
// metoda za iscrtavanje oblika
? ? ? // koje naredbe bi stavili ovdje?
}
Ako je oneShape varijabla tipa Shape, mogla bi se odnositi na objekt bilo kojeg od
tipova Rectangle, Oval, ili RoundRect. Kako se vrijednost varijable oneShape mijenja
u vrijeme izvršavanja programa tako se može odnositi na objekte različitih tipova.
Prilikom svakog izvršavanja izraza
oneShape.redraw();
Zapravo, redraw() metoda iz klase Shape neće nikad biti pozvana, a i nema razloga
kreirati objekte tipa Shape. Varijable tipa Shape mogu postojati, ali će objekti na
koje će se odnositi uvijek pripadati nekoj od podklasa klase Shape. Kažemo da
je Shape apstraktna klasa. Apstraktne klase su one koje ne služe stvaranju objekata,
nego samo kao osnova za stvaranje podklasa, a služe samo da bi se izrazile
zajednička svojstva svih podklasa.
Slično tome, može se reći da je redraw() metoda u klasi Shape apstraktna metoda,
jer nije zamišljena da je se ikad pozove. Zapravo, ona i nema što raditi, jer se svo
crtanje obavlja redraw() metodama podklasa Shape. Ona govori da svi Shape objekti
razumiju redraw() poruku i određuje zajedničko sučelje za sve redraw() metode u
potklasama Shape.
Klasa Shape i njena redraw() metoda su po svom značenju apstraktne, što se može
zapisati i dodavanjem modifikatora "abstract" u njihovu definiciju. Kod apstraktnih
metoda blok naredbi koje inače opisuju metodu zamijenjen točka-zarezom (;), a
njihova primjena mora biti zadana u svim podklasama apstraktne klase. Apstraktna
klasa Shape izgleda ovako:
abstract class Shape {
Svaka klasa u Javi ima svoju nadklasu, a ako ona nije definirana, automatski se
pridjeljuje nadklasa Object. Klasa Object je predefinirana klasa iz paketa java.lang i
jedina je klasa koja nema nadklasu.
Stoga su zapisi:
class myClass { . . .
i
class myClass extends Object { . . .
Sve klase su, izravno ili neizravno, podklase klase Object. To znači da objekt bilo
koje klase može biti pridjeljen varijabli tipa Object. Klasa Object predstavlja
najopćenitija svojstva koja imaju svi objekti, bez obzira kojoj klasi
pripadaju. Object je najapstraktnija od svih klasa.
Klasa Object koristi se kod rada s vrlo općenitim objektima. Na primjer, java ima
standardnu klasu java.util.Vector koja predstavlja listu objekata tipa Object.
Klasa Vector je vrlo pogodna jer Vector može sadržavati neograničen broj objekata i
raste prema potrebi. Budući su objekti u listi tipa Object, lista zapravo može
sadržavati objekte bilo kojeg tipa.
Program koji prati objekte tipa Shape koji su nacrtani na ekranu može spremiti te
oblike u Vector. Recimo da se Vector zove listOfShapes. Oblik oneShape može biti
dodan na kraj liste pozivanjem metode instance
"listOfShapes.addElement(oneShape)", a uklonjen s liste pozivom
"listOfShapes.removeElement(oneShape)". Broj oblika u listi se može dobiti pozivom
"listOfShapes.size()", a i-ti objekt se poziva izrazom "listOfShapes.elementAt(i)".
Potrebno je voditi računa o tome da ovaj poziv vraća tip Object a ne Shape. Budući
je poznat tip objekata, moguće je izlazni tip objekta pretvoriti u Shape izrazom
poput:
oneShape = (Shape)listOfShapes.elementAt(i).
Razmotrimo primjer ponovnog iscrtavanja svih olika u listi pomoću for petlje, u
kojemu je lijepo prikazana polimorfnost i objektno orijentirano programiranje:
for (int i = 0; i < listOfShapes.size(); i++) {
Shape s; // i-ti element liste, smatra se da je Shape
s = (Shape)listOfShapes.elementAt(i);
s.redraw();
}
Korisno je razmotriti i aplet koji koristi apstraktnu klasu Shape i Vector u kojemu je
spremljena lista oblika: