• No results found

Intoduction to Polymorphism

Da bi smo demonstrirali polimorfizam moramo napraviti program koji koristi nasljeđivanje. Mi smo napravili 4 klase :glavna klasa Apples, klasa Tuna i Potpie koje su subklase klase Food (superklasa). Klasa Food:

public class Food { public void eat(){

System.out.println("this food is great"); }

}

Klasa Tuna:

public class Tuna extends Food{ public void eat(){

System.out.println("this Tuna is great"); }

}

Klasa Potpie:

public class Potpie extends Food{ public void eat(){

System.out.println("this Potpie is great"); }

}

Kao sto vidimo mi smo overwrite (pisali preko) u klasama Tuna i Potpie na nacin da smo ime nasljedene metode kopirali i izmjenili joj tjelo.

Kada kreiramo objekte npr za Tuna klasu mi bi smo ukucali: Tuna tunaO = new Tuna( ); - vidimo da na dva mjesta imamo Tuna. Zasto nam to treba? Prvo Tuna i zadnje Tuna nisu isto. tunaO je refernce variable (reference znaci upucivanje, preporuka,..) , to znaci da kad god uputimo na promjenjivu tunaO mi upucujemo da kontrolise stvari u klasi Tuna( ) (tj zadnje Tuna ). Prvo Tuna je “data type” (vrsta podataka) , tako da moze kontrolisati Tuna vrstu podataka ,a tunaO je objekat vrste

Tuna (iz razloga sto tunaO= new Tuna( ); ).

Npr ako napisemo ovako Food tunaO = new Tuna( ); - I ovo je poprilicno uvod u polimorfizam. Ne

samo da je TunaO od Tuna vrste podataka vec je TunaO takodje i Food vrsta podataka. Ono sto sad mozemo uraditi , bilo sta sto nasljedjuje od superklase (tj. Food-a) moze biti assigned (dodjeljen) objektu tunaO. Tuna( ) s obzirom da nasljedjuje od Food moze biti dodjeljeno tunaO.

Kako ovo moze biti korisno, pokazacemo na primjeru , glavna klasa Apples izgleda : public class Apples {

public static void main(String args[]){ Food djordje[]=new Food[2]; djordje[0]=new Tuna(); djordje[1]=new Potpie(); for(int x=0;x<2;++x){ djordje[x].eat(); } } }

Najbrzi primjer kojim mozemo objasniti jeste da napravimo polymorphic Array i on skladisti objekte od razlicitih klasa u prilicno superklasa vrsti.

Napravili smo : Food djordje[ ] = new Food[2]; - djordje[ ] – je Array objekat , i ovaj objekat je

Food vrste (iz razloga sto se ispred djordje [] nalazi Food ) , s obzirom da imamo nesto Food vrste on

moze “hold” (drzati,posjedovati) objekte Tuna i Potpie (iz razloga sto su Tuna i Potpie subklase superklase Food ).

Jedan od razloga koriscena polimorfizma su polymorphics arrays , i to bi bilo nesto poput ovoga:

For(int x=0;x<2;++x){ bucky[x}.eat( ); } – ono sto ovo radi jeste da ide kroz svaki od ovih objekata i

zove eat metodu. Prvo ide kroz prvi objekat djordje[0] kome je dodjeljenja Tuna klasa i zove tu metodu (eat). Zatim ide kroz drugi objekat djordje[1] kome je dodjeljena Potpie klasa i zove eat metodu. Ono sto ovo radi jeste da ide kroz svaki od objekata i zove eat metodu za svaki. Kad pokrenemo ovaj program dobicemo :

this Tuna is great this Potpie is great

Lekcija: 56 Polymorphic Arguments

Imamo 5 klasa: Klasa Fatty:

public class Fatty {

public void digest(Food x){ x.eat();

} }

Klasa Food:

public class Food { void eat(){

System.out.println("This food is great"); }

}

Klasa Potpie:

public class Potpie extends Food{ void eat(){

System.out.println("This Potpie is great"); }

}

Klasa Tuna:

public class Tuna extends Food{ void eat(){

System.out.println("This Tuna is great"); }

}

Za razliku od prosle lekcije u ovoj imamo jos jednu klasu Fatyy, u kojoj imao digest metodu tj:public

void diges (Food x) { x.eat( ); } , Kao sto vidimo u zagradi imamo(parametar) Food x sto znaci da ce

uzimati Food objekat. Sada mozemo uraditi nesto sa tim objektom. x samo znaci da ce se u toj metodi x odositi na taj objekat. U tjelu digest metode imamo x.eat( ); sto znaci da na Food objekat koji prosljedimo bice primjenjena metoda eat( ) .

Osim sto metoda digest moze prihvatiti Food objekat, ona takodje moze prihvatiti i svaki objekat subklase ( u ovom primeru subklase superklase Food su Tuna i Potpie.

I Glavna klasa Apples: public class Apllses {

public static void main(String args[]){ Fatty djordje = new Fatty(); Food fo = new Food();

Food po = new Potpie(); djordje.digest(fo); djordje.digest(po); }

}

Prvo smo napravili Fatty objekat i nazvali ga djordje. Zatim smo napravili Food objekat i nazvali ga

fo. Takodje smo napravili Potpie objekat koji se zove po( kao sto vidimo za razliku od objekata djordje i fo kod kojih imamo na dva mjesta ime klase , kod objekta po imao Food na pocetku i

Zasto smo uopste napravili Food objekat? Zato sto u klasi Fatty metoda digest uzima argument koji je

Food objekat.

djordje.digest(fo); - iz klase Fatty (pomocu objekta djordje) smo pozvali metodu digest koja zahtjeva

jedan argument tj. Food objekat , fo je upravo taj Food objekat. Takodje mozemo kao argument uzeti bilo koji objekat cija je klasa subklasa superklase Food .

Kada pokrenemo ovaj program dobijemo: This food is great

This Potpie is great

Dakle “This Food is great” se prikazalo na sledeci nacin:

1) imamo instrukciju u glavnoj klasi djordje.digest(fo) , djordje je Fatty objekat, digest je Fatty meteoda , dok je ovo u zagradi argument tj. u ovom slucaju fo ( objekat klase Food).

2) Kada odemo u klasu Fatty do metode digest vidimo da ona zahtjeva jedan Food objekat , koji smo mi dali (fo). Metoda digest tom Food objektu dodjeljuje ime x koje koristi unutar te metode( bilo koji Food objekat bi dobio to ime) .

3) Unutar digest metode imamo instrukciju x.eat ( sto u stvari znaci fo.eat), dakle ide dalje do eat metode u klasi Food ( jer je fo objekat klase Food ).

4) Metoda eat u klasi Food ima instrukciju(System.out.println(“This food is great”); ) koja se izvrsava i na ekranu se prikazuje “This food is great”

“This Potpie is great” se pokazalo na slican naci , sto je demonstracija da umjesto Food objekta kao parametar mozemo prosljediti bilo koji objekat koji predstavlja subklasu Food superklase.

Lekcije: 57 Overriding Rules (najvaznija pravila) i 58 Abstract and Concrete

classes

Klasa Fatty:

public class Fatty {

public void digest(Food x){ x.eat();

} } Klasa Food:

public class Food { void eat(){

System.out.println("This food is great"); }

}

Klasa Potpie:

public class Potpie extends Food{ void eat(){

System.out.println("This Potpie is great"); }

} Klasa Tuna:

public class Tuna extends Food{ void eat(){

System.out.println("This Tuna is great"); }

}

I Glavna klasa Apples: public class Apllses {

public static void main(String args[]){ }

}

U ovj lekciji cemo pokusati rasvljetiti neke stvari koje smo obradili u proslim lekcijama. U prosloj lekciji smo imali 5 klasa : glavnu Apples, superklasu Food, subklase klase Food: Tuna i Potpie , i klasa Fatty. U subklasama Tuna i Apples smo “overwrite” metodu eat( ) koja se nalazi takodje u superklasi Food . Svaki put kada zelimo u subklasi “overvrite” pisati preko neke metode iz superklase moramo sem istog imena metode staviti i iste argumente u zagradi (dakle ako je u superklasi void eat(

) , ako zelimo “overvrite” u subklasi mora pisati void eat( ) ) da pise void eat( int i) ) to vise nije

“overvrite” vec overloading a to je potpuno druga stvar ). Isto tako moramo i vratiti “return” istu stvar. Npr ako vracamo int u super klasi moramo vratiti int i u subklasama. Ova pravila postoje da bih smo imali consistency (dosljednost tj. konzistencija) a to nam osigurava da bilo kad pozovemo metodu , garantuje nam da mozemo koristiti i subklasu takodje( npr. Kod klase Fatty gdje digest metoda zahtjeva jedan Food objekat, ako sve overvrite metode u subklasama vracaju iste stvari i imaju iste argumente onda umjesto objekta Food mozemo staviti bilo koji objekat koji predstavlja njegovu subklasu). Isto takodje kad god overvrite metodu ne mozemo mjenjati iz public u private.

“Overloded” (preklopljena) metoda je metoda sa istim imenom ali koja ima drugacije argumente. To je potpuno nova metoda.

Klase Tuna i Potpie mogu imati neke svoje argumente tipa : boja oblik, miris, okus… , dok njihovoj superklasi Food ne mozemo odrediti takve argumente , zato sto je Food(hrana) sirok pojam , neznamo joj boju, oblik, miris, okus.. Postoje neke klase (npr Food) koje su previse opste i za koje ne zelimo praviti objekte. Ako neku klasu zelimo koristiti za “inheritance” nasljedje ili polimorfizam a ne zelimo da se mogu praviti objekti prije klase stavimo abstract ( npr za Food : abstract public class Food { ) i sada kada bih smo pokusali napraviti Food objekat dobili bih smo error.

Klase koje nemaju abstract zaglavlju klase , se zovu concrete (konkretan – stvaran, koji se moze opaziti culima ; suprotno: apstraktan).

Samo u apstraktnim klasama mozemo imati apstraktne metode(Dok concrete metode mozemo imati i u apstraktnim klasama s tim da moraju imati tjelo). Apstract metoda je metoda koja mora biti “overvriten”. Kada napravimo apstract metodu potrebno je da u superklasi da napisemo metodu bez tjela tj samo glavu metode. Npr. Apstraktna klasa Food, sa apstraktnom metodom eat :

apstract public class Food { public abstract void eat()

}

S obzirom da subklase Tuna i Potpie moraju da “overvrite” ovu metodu one moraju da imaju tjelo. Klasa Tuna:

public class Tuna extends Food{ void eat(){

System.out.println("This Tuna is great"); }

}

I klasa Potpie:

public class Potpie extends Food{ void eat(){

System.out.println("This Potpie is great"); }

}

Dakle kada god imamo apstraktnu metodu u superklasi(npr. eat metoda u Food klasi) , sve subklase (u ovom primjeru Tuna i Potpie ) moraju imati tu metodu ili drugim rjecimo sve subklase moraju da “implement” ili “overvrite” tu metodu. Ako subklase nemaju tu metodu pojavice se error u liniji gdje se nalazi glava klase ili header(zaglavlje). Implement znaci prilicno da moramo “overvrite” apstracktne metode.

Kada god vidimo error u kome se nalazi rjec visibility vjerovatno morate promjeniti iz private u public ili obrnuto ili dodati ili jedno ili drugo.

Lekcija: 59 Class to Hold Object

U ovoj lekciji cemo napraviti program koji uzima klasu i stavlja objekte u array. Scenario je ovakav : Imamo 4 klase: Glavna Apples, superklasu Animals, njene subklase Dog i Fish . I treba da napravimo novu klasu DogList u kojoj cemo napraviti array koji ce skladistiti objekte klase Dog.

Klasa Dog:

public class Dog { }

Klasa Animals:

public class Animal { }

Klasa DogList:

public class DogList {

private Dog[] thelist = new Dog[5]; private int i=0;

public void add(Dog d){ if(i<thelist.length){

thelist[i]=d;

System.out.println("Dog added at index "+i);

i++; } } }

Prvo smo napravili array: private Dog[ ] the list = new Dog[5] – Dog[ ] znaci da cemo u ovom array skladistiti Dog objekte , thelist je ime array-ja dok Dog[5] znaci da ovaj array skladisti 5 Dog objekata. Dallje smo napravili promjenjivu i koju cemo koristiti kao brojac(counter). Zatim smo napravili metodu pomocu koje cemo dodavati Dog objekte cije zaglavlje izgleda: public void

add(Dog d) - u parametrima smo definisali da ce primati Dog objekte i da ce oni u ovoj metodi biti

prestavljeni sa d. U tjelu metode smo napravili if statement: if(i < thelist.length) i ako je ovaj uslov u zagradi ispunjen (tj. provjerava da li je array pun ili ne) ako nije dodaje taj objekat i pripisuje mu indeks i (cija je pocetna vrijednost postavljena na nula) tj: thelist[i]=d ili imearray-a[indeks]=d; .

System.out.println(“Dog added at index “ +i); nam prikazuje sta se ustvari desava. i++; se povecava

da ne bih pripisali/dodali istom indeksu novi objekat. Glavna klasa Apples:

public class Apples {

public static void main(String args[]){ DogList DLO = new DogList(); Dog d = new Dog();

DLO.add(d); }

}

Napravili smo Doglist objekat i nazvali ga DLO i Dog objekat koji smo nazvali d. Zatim smo pomocu

DLO objekta iz DogList klase pozvali metodu add i stavili u parametrima objekat d koji predstavlja

klasu Dog.

Kada pokrenemo ovaj program dobicemo: Dog added at index 0

Lekcija: 60 Array Holding Many Objects

U prosloj lekciji smo napravili Array koji skladisti Dog objekte, ali sada je potrebno da napravimo Array koji ce da sadrzava Fish objekte. Mozemo predpostaviti posto ima mnogo zivotinja da bih smo mogli dobiti zahtjev da napravimo Array koji ce sadrzavati objekte od : Cat, Dolphin, Whale i koliko vec postoji zivotinja. Zato umjesto da za svaku ponaosob klasu pravimo poseban Array mi cemo napraviti Array koji ce biti univerzalan za sve zivotinje. Imamo 5 klasa: glavnu Apples, superklasu

Animals njene subklase Fish i Tuna, i univerzalnu AnimalList klasu koja ce imati Array koji ce biti u

mogucnosti da skladisti bilo koji objekat koji je predstavnik klase koja nasljeđuje klasu Animals (po logici tu spadaju sve zivotinje). Klasa Fish:

public class Fish extends Animal{ }

Klasa Dog:

public class Dog extends Animal{ }

Klasa Animal:

public class Animal { }

Klasa AnimalList:

public class AnimalList {

public Animal[] TheList = new Animal[5];

public int i=0;

public void add(Animal a){

if(i<TheList.length){

TheList[i]=a;

System.out.println("Animal added at index "+ i);

i++;

}

} }

Glavna Klasa Apples: public class Apples {

public static void main(String args[]){ AnimalList ALO = new AnimalList(); Dog d = new Dog();

Fish f = new Fish(); ALO.add(d);

ALO.add(f); }

}

Kada pokrenemo ovaj program dobicemo: Animal added at index 0 Animal added at index 1

Ovaj kod je identican onom iz prosle lekcije samo sto smo sada umjesto da pravimo za svaku novu klasu Array , izgradili jedan univerzalni u klasi AnimalList i za koju god subklasu superklase Animal (tj. za bilo koju zivotinju) nam zatreba taj Array imamo ga vec kreiranog.

Lekcija: 61 Simple Polymorphic Program

Napravicemo primjer na kome cemo prikazati kako polimorfizam moze biti koristan. Napravili smo 4 klase: Glavna Apples, superklasa Animal, subklase Dog i Fish.

Klasa Animal:

public class Animal { public void noise(){

System.out.println("Animals don't make noise"); }}

Klasa Dog:

public class Dog extends Animal{ public void noise(){

System.out.println("Dog: Ruff"); }}

Klasa Fish:

public class Fish extends Animal{ public void noise(){

System.out.println("Fish: Glurp Slurp "); }}

Dakle napravili smo noise metodu u klasi Animal , zatim smo istu tu metodu “overvrite” u klasama

Dog i Fish.

Glavna klasa Apples:

public class Apples {

public static void main(String args[]){ Animal[] thenoiselist = new Animal[2]; Dog d = new Dog();

Fish f = new Fish(); thenoiselist[0]=d; thenoiselist[1]=f;

for(Animal x:thenoiselist) x.noise();

} }

Prvo smo napravili Array thenoiselist , koji ce sadrzavati objekte tipa Animal (tj. moze sadrzavati objekte svih njenih subklasa). Zatim smo napravili objekte d i f koji predstavljaju klase Dog odnosno

Fish. Onda smo napravljenom Array-u dodjelili te objekte , tj. povezali smo indekse i objekte( thenoiselist[0]=d i thenoiselist[1]=f; ) .

Dalje smo napravili pobloljsanu for petlju( to je prilicno specijalna petlja koja prolazi kroz Array):

for(Animal x: thenoiselist) – Animal je vrsta podataka, x je indentifikator kojim ce se nazivati objekti

u ovoj petlji dok je thenoiselist Array kroz koji ce ova petlja ici. U tjelu petlje imamo : x.noise( ) sto u stvari znaci da kada petlja prodje kroz Array uzmima tekući element(tj. objekat) dodjeli mu indetifikator x i pokrene metodu noise.

Kada pokrenemo ovaj program dobicemo: Dog: Ruff

Related documents