11.9.23

Java metode: povratna vrednost metoda

Besplatni Java kurs - 61. deo
Ovo je samo jedan od članaka koji zajedno čine besplatan Java tutorijal.

U prvom članku o Java metodama objasnio sam šta su metode i kako se koriste. Podsećanja radi, metoda koju sam koristio u primeru zvala se citaj i bila je napisana u klasi Knjiga, a ceo kôd je izgledao ovako:

class Knjiga {
    public String naslov;
    public String autor;
    public int brStranica;

    public Knjiga(String naslov, String autor, int brStranica){
        this.naslov = naslov;
        this.autor = autor;
        this.brStranica = brStranica;
    }

    public void citaj(){
        System.out.println("Citam knjigu " + this.naslov);
    }
}

class Rad {
    public static void main(String args[]){
        Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
        Dina.citaj();
    }
}

Izvršavanjem navedenog kôda dobija se sledeći izlaz:

Citam knjigu Dina

Metoda citaj je veoma jednostavna. Njen jedini zadatak je ispisivanje poruke koja kaže koju knjugu čitam. Metoda citaj sadrži jednu jedinu liniju kôda:

System.out.println("Citam knjigu " + this.naslov);

Hajde sada da dodamo još jednu metodu u klasu Knjiga. Metoda će se zvati uzmiNaslov. Prvo ću napisati celokupan novi kôd, pokazati šta će biti rezultat njegovog izvršavanja i na kraju ću detaljno objasniti kako nova metoda radi.

Metode sa povratnom vrednošću

Nova verzija kôda koji koristi metodu sa povratnom vrednošću uzmiNaslov izgleda ovako:

class Knjiga {
    public String naslov;
    public String autor;
    public int brStranica;

    public Knjiga(String naslov, String autor, int brStranica){
        this.naslov = naslov;
        this.autor = autor;
        this.brStranica = brStranica;
    }

    public void citaj(){
        System.out.println("Citam knjigu " + this.naslov);
    }

    public String uzmiNaslov(){
        return this.naslov;
    }
}

class Rad {
    public static void main(String args[]){
        Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
        Dina.citaj();
        Dina.uzmiNaslov();
    }
}

Izvršavanjem najnovije verzije kôda dobija se sledeći izlaz:

Citam knjigu Dina

Iako sam dodao novu metodu i zatim je pozvao, izlaz je isti kao i ranije. Zašto?

Nova metoda uzmiNaslov izgleda ovako:

public String uzmiNaslov(){
    return this.naslov;
}

Hajde da je uporedimo sa metodom citaj koja izgleda ovako:

public void citaj(){
    System.out.println("Citam knjigu " + this.naslov);
}

Za razliku od metode citaj koja poziva metodu println pomoću koje ispisuje svoju poruku, naša nova metoda uzmiNaslov ne radi ništa slično. Naša nova metoda ima samo jednu liniju kôda:

return this.naslov;

Ključna reč return u programskom jeziku Java služi da nešto vrati iz metode. Ali šta?

Neposredno uz ključnu reč return nalazi se this.naslov i upravo to će (u ovom slučaju) biti vraćeno iz metode uzmiNaslov. Može se reći da je this.naslov povratna vrednost metode uzmiNaslov.

Ali povratna vrednost ne može biti bilo šta. Tačnije, povratna vrednost ne može biti bilo kog tipa.

Tip povratne vrednosti metoda

Hajde da još jednom uporedimo metode citaj i uzmiNaslov. Obe imaju isti modifikator pristupa public. Ono što je različito se nalazi između modifikatora pristupa i naziva metoda. Ispred naziva metode citaj stoji tip void, a ispred naziva metode uzmiNaslov stoji tip String. Upravo tip ispred naziva metode određuje tip povratne vrednosti te metode.

Tip povratne vrednosti metode uvek mora biti ispoštovan, odnosno, metoda uvek mora vratiti vrednost tog tipa.

U slučaju metode citaj tip povratne vrednosti je void, što znači da ova metoda ne sme vraćati ništa. Zato ova metoda mora ili ostati bez return instrukcije, ili koristiti return bez ičega neposredno iza return u istoj naredbi. Drugim rečima, ako se koristi return u metodi čiji je povratni tip void onda ne sme biti ničega između return i ;.

Naša metoda citaj koja izgleda ovako:

public void citaj(){
    System.out.println("Citam knjigu " + this.naslov);
}

radila bi ispravno ako bismo dodali „prazan” return na njenom kraju:

public void citaj(){
    System.out.println("Citam knjigu " + this.naslov);
    return;
}

Ali to nije neophodno, jer svaka metoda podrazumevano ne vraća ništa ako izostaviš return. Međutim, ako bismo uz return stavili bilo šta, onda kôd više ne bi bio ispravan. Npr. ova verzija metode bi prouzrokovala grešku:

public void citaj(){
    System.out.println("Citam knjigu " + this.naslov);
    return 1;
}

Java kompajler jednostavno neće dozvoliti da uz return stoji ni broj 1, niti bilo šta drugo, jer je povratna vrednost metode definisana kao tip void. Da bi se greška u prethodnom primeru ispravila, potrebno je ili promeniti tip povratne vrednosti u definiciji metode u int, ili ispraviti kôd tako da metoda ne vraća ništa.

Hajde da sada proučimo našu drugu metodu, uzmiNaslov, koja izgleda ovako:

public String uzmiNaslov(){
    return this.naslov;
}

Metoda uzmiNaslov ima definisan tip String kao povratnu vrednost. To znači da ova metoda mora da vrati neki String. Ako obratiš pažnju, videćeš da je promenljiva naslov u klasi Knjiga definisana upravo kao tip String. Zato metoda uzmiNaslov radi ispravno. Kada bismo promenili metodu tako da ne vraća String, onda više ne bi radila i došlo bi do greške.

Ako, primera radi, izbrišemo this.naslov i ostavimo samo return, metoda više neće biti ispravna:

public String uzmiNaslov(){
    return;
}

Ako i dalje nisam odgovorio na pitanje sa početka koje je glasilo: „Iako sam dodao novu metodu i zatim je pozvao, izlaz je isti kao i ranije. Zašto?”

Na ovo pitanje još uvek nisam odgovorio jer sve što sam do sada objasnio je zapravo samo polovina priče o povratnim vrednostima metoda. Do sada sam objasnio kako se metoda priprema da bi mogla da vrati željeni tip pomoću definisanja njene povratne vrednosti. I objasnio sam kako se zapravo nešto tog tipa vraća pomoću ključne reči return. Obe stvari se odnose na metodu.

Ali povratna vrednost neke metode nikada ne postoji zbog same metode, već zato što je nešto što se nalazi u toj metodi toliko važno da želimo da ga nekako izvučemo iz metode i koristimo negde izvan te metode. Zato je jako važno razumeti gde se to vraća nešto što data metoda vraća pomoću naredbe return.

Prihvatanje povratne vrednosti metode na mestu njenog poziva

Kad god se neka metoda pozove, dešavaju se dve stvari:

  • metoda se izvršava
  • metoda vraća svoju povratnu vrednost na mesto poziva

Hajde da ponovo bacimo pogled na poziv metode uzmiNaslov. Za to je dovoljno da se usredsredimo na metodu main iz našeg primera:

public static void main(String args[]){
    Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
    Dina.citaj();
    Dina.uzmiNaslov();
}

U metodi main postoje tri linije kôda. U prvoj liniji stvara se objekat Dina tipa Knjiga. U drugoj liniji se poziva metoda citaj što za ishod ima ispisivanje sledeće poruke na izlazu:

Citam knjigu Dina

U trećoj liniji kôda poziva metoda uzmiNaslov. Ova metoda ima povratni tip String i sadrži jednu jedinu liniju kôda koja vraća this.naslov. Kako je metoda pozvana pomoću objekta Dina, to znači da će metoda uzmiNaslov vratiti String koji sadrži sadržaj promenljive naslov objekta Dina. Tačnije, metoda uzmiNaslov će u ovom slučaju vratiti "Dina" na mesto svog poziva. A mesto poziva je upravo treća linija kôda u metodi main.

Kako metoda uzmiNaslov ne radi ništa drugo osim što vraća "Dina" na mesto svog poziva, kôd metode main će suštinski biti jednak sledećem:

public static void main(String args[]){
    Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
    Dina.citaj();
    "Dina";
}

Posmatranjem navedenog kôda sada je očigledno zašto se dodavanjem metode uzmiNaslov u klasu Knjiga i njenim pozivanjem u metodi main ništa nije promenilo na izlazu. Nije dovoljno samo staviti neki String u neku liniju kôda da bi se on ispisao. Potrebno je upotrebiti neku metodu koja služi za ispis, npr, metodu println:

public static void main(String args[]){
    Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
    Dina.citaj();
    System.out.println("Dina");
}

Naravno, ne želimo da tek tako ispišemo "Dina" već da to ide preko metode uzmiNaslov. Zato ćemo se vratiti korak nazad pre nego što sam poziv metode uzmiNaslov zamenio stringom Dina, ali ćemo kao i u poslednjem primeru iskoristiti i metodu println. Tačnije, staviću poziv metode uzmiNaslov unutar poziva metode println:

public static void main(String args[]){
    Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
    Dina.citaj();
    System.out.println(Dina.uzmiNaslov());
}

Izvršavanjem najnovije verzije kôda konačno dobijamo drugačiji ispis:

Citam knjigu Dina
Dina

Po prvi put koristimo povratnu vrednost metode van same metode. Sada u poslednjoj liniji metode main pozivamo metodu uzmiNaslov koja nam vraća "Dina" na mestu na kojem smo je pozvali. U primeru se vidi da smo metodu uzmiNaslov pozvali unutar (zagrada) metode println i upravo zato se na ekranu ispisuje "Dina".

I konačno možemo da odgovorimo na ono čuveno pitanje. Razlog što je ispis bio isti kada smo prvobitno dodali metodu uzmiNaslov je bio taj što njenu povratnu vrednost jednostavno nismo koristili. Za razliku od tog (prvog) primera, poslednja verzija našeg kôda koristi povratnu vrednost metode uzmiNaslov tako što je ispisuje na ekran. Kad smo već kod poslenje verzije kôda, ta kraj ću navesti kako izgleda u celosti:

class Knjiga {
    public String naslov;
    public String autor;
    public int brStranica;

    public Knjiga(String naslov, String autor, int brStranica){
        this.naslov = naslov;
        this.autor = autor;
        this.brStranica = brStranica;
    }

    public void citaj(){
        System.out.println("Citam knjigu " + this.naslov);
    }

    public String uzmiNaslov(){
        return this.naslov;
    }
}

class Rad {
    public static void main(String args[]){
        Knjiga Dina = new Knjiga("Dina", "Frenk Herbert", 704);
        Dina.citaj();
        System.out.println(Dina.uzmiNaslov());
    }
}


Pročitaj i nastavak:

Besplatni Java kurs - 62. deo - Java metode: parametri metoda

No comments:

Post a Comment