autor: Ivan Kupka

Verzia 1

home uvod K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14

Java 3

 

Polia, metódy, konštruktory

 

Cieľom tejto časti  je oboznámiť sa podrobnejšie s poľam a s definovaním metód v Jave.Ďalšie témy:Prvá informácia o premenných inštancie a o konštruktore. Vytváranie náhodných čísel.

 

Polia po druhý raz

  Na pole sa môžeme dívať ako na kontajner, ktorý má presne určený počet prvkov a ich typ. Pole uskladňuje vždy len prvky jednej triedy. Rozmer poľa

nám vráti premenná length, pole mojePole  má dĺžku

int dlzka = mojePole.length ;

 Pole môže mať viac rozmerov, nemusí byť však „pravidelné“. T. j. napríklad v prípade dvojrozmerného poľa všetky jeho „riadky“, či „stĺpce“ nemusia byť rovnako dlhé. Pozrime si nasledovné trojrozmerné pole typu String[][][], ktoré v sebe uchováva informáciu o prezývkach chlapcov, chodiacich do posilovne. Orientáciu sťažuje, že sú medzi  nimi dvaja Petrovia  Novákovia. Jozefov a Karolov je tu tiež viac. Spolu chodí do posilovne  9 chlapcov. Ich prezývky znázorňuje nasledujúca tabuľka:

 

Mena       Priezviska:

Novák

Kováč

Peter

Petko, Pato

              -

Jozef

Jozino, Jojo, Pepo

Prcek

Karol

Kajo

Kladivo, Oheň

 

 

Definíciu poľa a tlačenie niektorých prezývok uvidíme v nasledujúcom kóde. Pozor! Keď budete definovať viacrozmerné polia, musíte mať najprv definované  menšie rozmery, indexy,  kým začnete definovať tie väčšie, či dokonca priraďovať indexom konkrétne hodnoty.

 

Kód P3.1

 

public class JozefoviKamosi {

    public static void main(String[] args){

    /*

    Prva suradnica nasledujuceho pola vyjadruje meno:

    0. Peter

    1. Jozef

    2. Karol

    Druha suradnica priezvisko

    0. Novak

    1. Kovac

   

    napriklad prvok [1][1] obsahuje prezyvky vsetkych Jozefov Kovacov,

      je to jednorozmerne pole stringov

   

    */

         // vytvaram polozky pre mena

    String[][][] prezyvky = new String[3][][];

 

    // meno Peter ma len jedno priezvisko, s dvomi prezyvkami

    prezyvky[0] = new String[1][2];

    // zapiseme tie prezyvky

     prezyvky[0][0][0] = "Petko";

     prezyvky[0][0][1] = "Pato";

    // meno Jozef  ma dve priezviska

    prezyvky[1] = new String[2][];

    //u  Jozefov zaplnime  priezvisko Novak prezyvkami

    prezyvky[1][0] = new String[]{"Jozino","Jojo","Pepo"};

    // teraz Jozefi a priezvisko Kovac

    //prezyvky[1][1][0] = "Prcek";

    /* toto sice prekladac bez problemov prelozi

     ale program za behu zhavaruje a zahlasi

     "java.lang.NullPointerException"

      chyba bola v tom, ze musime najprv urcit,

       ake velke bude pole prezyvky[1][1]  este sme to nedeklarovali:

       */

      prezyvky[1][1] = new String[1];

      prezyvky[1][1][0] = "Prcek";

 

          // teraz Karolovia, najprv polia priezvisk

     prezyvky[2] = new String[2][];

     // teraz dlzky poli prezyvok v jednotlivych priezviskach

     prezyvky[2][0] = new String[1];

     prezyvky[2][1] = new String[2];

     //prezyvka Karola Novaka:

       prezyvky[2][0][0] ="Kajo";

     //prezyvky Karolov Kovacov

        prezyvky[2][1][0] = "Kladivo";

       prezyvky[2][1][1] = "Ohen";

   

    System.out.println("Tlacim prezyvky Jozefov:");

    for(int indexPriezviska = 0; indexPriezviska < prezyvky[1].length;   indexPriezviska++){

            for(int indexPrezyvky = 0; indexPrezyvky < prezyvky[1][indexPriezviska].length; indexPrezyvky++){

                 

    System.out.print( prezyvky[1][indexPriezviska][indexPrezyvky]  + " " );  

            }//EOmalyFor

    }//EOvelkyFor

     System.out.println();

     

     

     }//EndOFmain

}//EndOfClass

   

Metódy

  Základom každej triedy sú jej premenné a metódy. Vo všeobecnosti by každá metóda mala realizovať iba jednu úlohu. Každá metóda má samozrejme meno, podľa ktoré ho ju v programe voláme – spustíme.

Metódu musí zavolať objekt tej triedy, v ktorej je metóda definovaná. A to takto:  nazovObjektu.nazovMetody(parametre);  . (Až na statické metódy, ktoré  stačí volať menom triedy:  MenoTriedy.nazovMetody(parametre); )

Metóde môžeme dať akékoľvek meno okrem – kľúčových slov jazyka Java . (Bolo by dosť hlúpe pomenovávať metódy slovami ako if, double. while  private). Takisto názov  „main()“  si rezervujme pre metódu, ktorou začína náš program.

 

Statické metódy a metódy inštancie

V nasledujúcom príklade si všimnite  rozdiel medzi používaním statickej metódy - tzv. metódy triedy - "pis"   a metódy instancie "tlac". Preštudujte aj správanie sa podobnej metódy "tisk", ktorá má návratovy typ  "String".

Kód P3.2

public class Pisanie {

         

          public static void pis(String s) {

                    System.out.println(s);

          }

         

          public void tlac(String s){

                    System.out.println(s);

          }

                   

          public String tisk(String s){

                    System.out.println(s);

                    int i = s.length();

                    //zapise do Stringu aky dlhy text tlaci

                    String vystup = "Metoda \"tisk\" vytlacila text s " +(new            Integer(i)).toString() +" znakmi.";

                    return vystup;

          }

                   

          public static void main(String[] args){

            String pozdrav = "ta zdravi."; 

          Pisanie.pis("Pisanie.println " + pozdrav);

          //Pisanie.tlac("Pisanie.tlac " + pozdrav);

    //non-static method tlac(java.lang.String) cannot be referenced from a 

    //        static context

    Pisanie pisar = new Pisanie();

   

    pisar.tlac("pisar.tlac " + pozdrav);    

    pisar.pis("pisar.pis " + pozdrav);    

   

    String coVytlacilTisk = pisar.tisk("pisar.tisk " + pozdrav);

    System.out.println(coVytlacilTisk);  

          }//endOfMain

         

}//endOfPisanie

         

          /*  Vystup:

          Pisanie.println ta zdravi.

 

pisar.tlac ta zdravi.

 

pisar.pis ta zdravi.

 

pisar.tisk ta zdravi.

 

Metoda "tisk" vytlacila text s 21 znakmi.

 

Process Exit... */

 

 

Všeobecný tvar metódy

 Všeobecný tvar metódy vyzerá takto:

 

   typMetody navratovyTyp menoMetody(zoznamParametrov){

 

    //telo metody

 

}

 

typMetody netreba nutne použiť, ak sa v opise metódy nachádza, ide o informáciu, či je metóda prístupná aj zvonku triedy, poprípade alebo či je statická (napr:  „public static“  alebo „private“ ).

navratovyTyp je označenie typu premennej, alebo dátového typu, ktorý metóda vracia. Napr: String alebo double .

menoMetody  je meno, ktoré sme pre metódu zvolili. Malo by byť, pokiaľ je to možné, výstižné.

ZoznamParametrov vymenováva typy jedonotlivých parametrov, s akými metóda pracuje. Je napísaný v tvare zoznamu, kde každá položka je dvojica typ a identifikátor. Položky oddeľujeme čiarkou. Napríklad:

 

   public void  napisNiekolkoKrat(String totoNapis, int tolkotokratToNapis) {

 

    for(int i = 1; i <= tolkotokratToNapis; i++) System.out.println(totoNapis);

 

}

 

Keď metóda nevracia žiadnu hodnotu, jej typ musíme označiť slovom void. Ostatne, ak by sme zabudli, prekladač nás na túto povinnosť upozorní. Kód:

   public   napisNiekolkoKrat(String totoNapis, int tolkotokratToNapis) {

 

    for(int i = 1; i <= tolkotokratToNapis; i++) System.out.println(totoNapis);

 

}

 

 má za následok hlásenie:

invalid method declaration; return type required

        public napisNiekolkoKrat(String totoNapis, int tolkotokratToNapis) {

               ^

1 error

 

 

Príkaz return

 Príkaz return ukončuje metódu. Ak je metóda typu void, ukončí svoju prácu najneskôr vtedy, keď narazí na poslednú pravú zátvorku. Ak sa však pred zátvorkou v priebehu vykonávania metódy vyskytne príkaz “return;”  metóda ukončí svoju činnosť.

Metódy, ktoré deklarujú, že vracajú hodnotu, musia tak počas svojho behu urobiť. T. j. metóda typu

 

    long  velkostPremii(boolean jeToKamarat?){

 

musí (v každej svojej možnej vetve) nakoniec vrátiť premennú typu long. Napríklad takto:

       long  premie = 0;

       if(jeToKamarat?) {

         premie = 1000000;

       }

        return premie;

 

Metóda je jednoznačne určená svojim názvom a zoznamom argumentov

 

Kód P3.3

public class Metody {

   

    public String dajInfo(String s){

        System.out.println("\"" + s + "\" zacina na pismeno " + s.substring(0,1));

        return "skumal som retazec " + s;

    }

    /*

    public int dajInfo(String s){

      int dlzkaStringu = s.length();

      System.out.println("Dlzka stringu je: " + dlzkaStringu);

      return dlzkaStringu;  

    }

    */

    public static void main(String[] kuriatko){

        Metody objekt = new Metody();

        String metodaVratila = objekt.dajInfo("Popokatepetl");

        System.out.println("Metoda vratila: " + metodaVratila);

       

    }//EndOfmain

}//EndOfClass

 

 

   Ak by sme odkomentovali definíciu metódy public int dajInfo(String s),

prekladač by nás upozornil na chybu:

 

Metody.java:8: dajInfo(java.lang.String) is already defined in Metody

    public int dajInfo(String s){

                   ^

1 error

 

  Z toho, čo sme povedali vyššie ale plynie, že pokojne môžeme definovať metódu

  public String dajInfo(int i), pretože táto sa od pôvodnej public String dajInfo(String s) líši argumentom.

 

Používanie premenných inštancie

 

 Ako o tom budeme hovoriť podrobnejšie neskôr, každá trieda môže mať svoje premenné. Pri vytvorení nového objektu sa inicializujú aj premenné inštancie. Dôležité je vedieť, že metódy majú k týmto premenným prístup a môžu ich vo svojom tele používať. Na premenné sa v metóde odvolávame bez vymenovania objektu a bez bodky. Keď metódu v programe použijeme, bude jasné, aký objekt ju volá a aké sú hodnoty premenných tohto objektu-inštancie.

  Ilustrujme si vyššie povedané na príklade triedy Netvor.

 

Kód P3.4

public class Netvor{

    // premenne instancie:

    int pocetOci;

    String menoNetvora;

    // verejny konstruktor, ktory vytvori Netvora s pozadovanym poctom oci

    // a prislusnym menom

    public Netvor(String meno,int kolkoOci){

        pocetOci = kolkoOci;

        menoNetvora = meno;

    }

    //metoda otvorOci, ktora opisuje Netvorovo prebudzanie

    // a pouziva premenne pocetOci a menoNetvora

   

    public void otvorOci(){

        System.out.println("Netvor " + menoNetvora + " sa prebudza.");

        for(int i = 1; i <= pocetOci; i++){

              System.out.println("Otvara svoje " + i +". oko.");

         }

    }//EOotvorOci

   

    public static void main(String[] args){

    Netvor prvyNetvor = new Netvor("Garg",5);

    Netvor druhyNetvor = new Netvor("Monk",3);

    prvyNetvor.otvorOci();

    druhyNetvor.otvorOci();

    }

}//EOClass

 

T je výstup z programu:

 

Netvor Garg sa prebudza.

Otvara svoje 1. oko.

Otvara svoje 2. oko.

Otvara svoje 3. oko.

Otvara svoje 4. oko.

Otvara svoje 5. oko.

Netvor Monk sa prebudza.

Otvara svoje 1. oko.

Otvara svoje 2. oko.

Otvara svoje 3. oko.

Process Exit...

 

Metódy jednej triedy  môžu vo svojom tele volať iné metódy tej istej triedy

Kód P3.5

 

public class NapisVetu {

   

    public void pisVetu(){

        napisPodstatneMeno();

        napisPrislovku();

        napisSloveso();

        napisZaverecnyZnak();

    }

   

 

    private void napisPodstatneMeno(){

        //vyberie nahodne jedno zo styroch slov a vytlaci ho na konzolu

        int i = (int)(Math.random()*4);

        switch(i){

          case 0: System.out.print("Princ ");   

          break;

         

          case 1: System.out.print("Jozo ");

          break;

         

          case 2: System.out.print("Robinson Crusoe ");

          break;

         

          case 3: System.out.print("Forrest Gump ");

        }

    }

   

    private void napisPrislovku(){

        //vyberie nahodne jedno zo styroch slov a vytlaci ho na konzolu

        int i = (int)(Math.random()*4);

        switch(i){

          case 0: System.out.print("pomaly ");

          break;

         

          case 1: System.out.print("smutne ");

          break;

         

          case 2: System.out.print("dojate ");

          break;

         

          case 3: System.out.print("zamyslene ");

        }

    }

   

 

    private void napisSloveso(){

        int i = (int)(Math.random()*4);

        switch(i){

          case 0: System.out.print("spieva");   

          break;

         

          case 1: System.out.print("zaspal");

          break;

         

          case 2: System.out.print("obeduje");

          break;

                     

                      case 3: System.out.print("odisiel");

                 }

    }

   

    private void napisZaverecnyZnak(){

      int i = (int)(Math.random()*4);

      switch(i){

            case 0: System.out.println("."); 

      break;

         

      case 1: System.out.println("?");

      break;

         

      case 2: System.out.println("!");

      break;

                     

            case 3: System.out.println("...");

            

    }

     }

   

   

   

    public static void main(String[] args){

   

    NapisVetu pisar = new NapisVetu();

    pisar.pisVetu();

    }

 

Metóda môže vo svojom tele volať aj samu seba

 

Toto, takzvané rekurzívne použitie metódy treba v praxi dobre zvážiť. Často máme nad procesom lepšiu kontrolu, respektíve ušetríme čas, ak použijeme vhodný cyklus.

Kód P3.6

public class UsporneOpatrenia{

   

    public void uspor(String totoSkrat){

        // najde poziciu poslednej medzery v texte - ak existuje

        int poziciaPoslednejMedzery = totoSkrat.lastIndexOf(' ');

       

        if(poziciaPoslednejMedzery > -1) {

       //ak tam medzera bola  text skrati a vytlaci

 

        String skratenyText = totoSkrat.substring(0,poziciaPoslednejMedzery);

        System.out.println(skratenyText);

        //tu metoda vola samu seba so skratenym textom v argumente:

        uspor(skratenyText);

        }

        // ak metoda medzeru v texte nenasla:

        else{

          System.out.println("Uz sa usetrilo vsetko, co sa dalo.");

        }

    }

   

    public static void main(String[] args){

        String mameSa = "zijeme tu vsetci velmi veselo, obklopeni luxusom a blahobytom";

       

        UsporneOpatrenia skrtic = new UsporneOpatrenia();

         skrtic.uspor(mameSa);

   

   

    }//EndOfmain

 

Výstup programu:

 

zijeme tu vsetci velmi veselo, obklopeni luxusom a

zijeme tu vsetci velmi veselo, obklopeni luxusom

zijeme tu vsetci velmi veselo, obklopeni

zijeme tu vsetci velmi veselo,

zijeme tu vsetci velmi

zijeme tu vsetci

zijeme tu

zijeme

Uz sa usetrilo vsetko, co sa dalo.

 

 

Metóda toString()

 

  Je definovaná v triede Object, umožňuje vytlačiť textovú reprezentáciu objektu. Aby táto reprezentácia mala podobu, akú si želáme, metódu treba „prekryť“, t. j. definovať znova. Spustite si nasledujúci kód, potom ho spustite po odkomentovaní riadkov, definujúcich metódu toString().

Kód P3.7

// metoda toString()

 

public class Word {

    // ako sa pise?

    private String text;

    // ake je dlhe?

    private int dlzka;

    // prislusne sety a gety....

    public String getText(){

        return text;

    }

    // konstruktor

   

    public Word() {

    System.out.println("Word, konstruktor bez argumentov.");   

       

    }

    public Word(String obsah){

        text = obsah;

        dlzka = text.length();

        System.out.println("Konstruktor Word vytvoril slovo s textom \" " +      text +   "\" a dlzkou " +dlzka);

    }

   

    public String napisOdzadu(){

        StringBuffer otoc = new StringBuffer(text);

        otoc = otoc.reverse();

        return otoc.toString();

    }

          // spusti program, potom odkomentuj nasledujuce 3 riadky a spusti ho znova

          //public String toString(){

            //return text;

          //}

          //

         

 

          public static void main(String[] args){

                   

                    Word dravec = new Word("tiger");

                    System.out.println(dravec + " odzadu: :" + dravec.napisOdzadu());

          }//EOMain

}//EOClass

   

 

Cvičenia

Riešenie Cv2.4 z minulých cvičení :

public class Zmrzlina{

public static void prt(String s){

        System.out.println(s);

    }

public static void main(String[] args){

          for(int i = 1; i < 100; i++) {

            prt("\n Oci,kup mi zmrzlinu.");

             if(i > 4) {

              prt("Nic ti nekupim.Bude ta boliet brucho!");

                    break;

             prt("Kupil som  ti " + i +"X zmrzlinu.");

                               

                               if(i > 2) {

                                         continue;

                               }

                               prt("Chces este jednu?");

                    }//endOfFor

 

                   

          }//endOfMain

}//endOfClass

      

 

 

Cv3.1

  Pozmeňte  program z Cv2.4 tak, že pri násobení matíc budete používať metódu, ktorá vypočíta skalárny súčin vektorov.  Rozšírte program o metódu  „ tlacMaticu()”, ktorá zobrazí jednotlivé riadky matice

pod sebou.  Naprogramujte metódu ktorá zistí, či sa i-y stĺpec matice skladá – neskladá zo samých núl.

 

Cv3.2 

V kóde P3.1 dopíšte cyklus, ktorý vytlačí prezývky všetkých Kováčov. Pritom  cyklus dopredu nevie, ktoré krstné mená pre toto priezvisko sú obsadené a ktoré nie.

Cv3.3  Spustite všetky programy z prednášky. Sledujte, či ich výstupy zodpovedali vášmu očakávaniu.

 

Cv3.4  Naprogramujte metódu, ktorá náhodne vylosuje 6 čísel športky.

 

 

Riešenia:

Riešenie Cv3.2

System.out.println("Prezyvky Kovacov su:");

      for(int meno = 0; meno < prezyvky.length ; meno++){

        for(int priezvisko = 0; priezvisko < prezyvky[meno].length; priezvisko++){

          for(int prezyvka = 0; prezyvka < prezyvky[meno][priezvisko].length; prezyvka++){

            // tlac, ak sa jedna o kovaca, t. j. o prizvisko s indexom jedna

              if(priezvisko==1){

                System.out.print(prezyvky[meno][priezvisko][prezyvka] + " ");

              }//EOIf

            }//EOFor3

        }//EOFor2

      }//EOFor1

     System.out.println();

 

Riešenie CV3.4

public class Sportka {

         

          public void losuj(){

          // vytvori pole 49 cisel

          int[] cisla = new int[49];

          // umiestni do nich hodnoty od 0 do 48

          for(int j = 0; j < cisla.length; j++) cisla[j] =j;

          // ide 6x losovat a tlacit vysledky

          System.out.println("Vysledky posledneho tahu sportky su: ");

         

          // vylosuje nahodny index, vylosovane cislo "uprace" a losuje uz len zo zvysnych

          for(int krok = 0; krok < 6; krok++){

            int nahodnyIndex =   krok + (int) (Math.random()*(49 - krok));

      int totoVytlacAUprac = cisla[nahodnyIndex];

      //tlaci cislo o 1 vacsia ako je totoVytlacAUprac

       System.out.print((totoVytlacAUprac+1) + " ");

   // upratuje a vymiena prvky

    cisla[nahodnyIndex] = cisla[krok];

     cisla[krok] = totoVytlacAUprac;

          }//EndOfFor

    // odriadkuj

            System.out.println();

          }//EndOfMethod

                   

            public static void main(String[] args){

                   

                      Sportka hra = new Sportka();

                      hra.losuj();

            }//EOMain

          }//EOClass

                             

                   

                   

         

END

© Ivan Kupka

home uvod K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14

Vaše komentáre: kupka@fmph.uniba.sk