Ilkka Koivistoinen 13.02.2002

Edellinen

Seuraava

 

Metodien ylikirjoittaminen
Muodostimen ylikirjoittaminen
super -muuttuja

8.6 Metodien ylikirjoittaminen

Palataan esimerkkiin 43. Siinä periytettiin luokasta omena uusi luokka soseOmena, johon laitettiin yksi uusi jäsenmuuttuja soseena. Kun testiohjelmassa E43 käytettiin omena -luokan tulostaAttribuutit() -metodia, ei tulosteena saada tietenkään soseena -jäsenmuuttujan arvoa. Voimme tehdä uuden metodin luokkaan soseOmena seuraavasti.

class soseOmena extends omena {
  boolean soseena=false;
  public soseOmena(String vari1, String maku1, boolean matoisuus1, boolean soseena1) {
    vari = vari1; maku = maku1; matoisuus = matoisuus1; soseena = soseena1;
  }
  void tulostaAttribuutit(){
    System.out.println(" Vari: " + vari + "\n Maku " +maku+ "\n Matoisuus " + matoisuus+" Soseena "+soseena);
   }
  }
}

Kääntämällä tämän tavukoodiksi (älä tee sitä vielä. Lue ensin seuraava kappalle "Muodostimen ylikirjoittaminen"), voimme ajaa esimerkin E43 uudestaan ja havaitaan, että nyt kirjoitettu metodi tulostaAttribuutit() korvaa luokassa omena olevan saman nimisen metodin. Java ottaa käyttöön periytyvyysluettelossa ensiksi mainitun metodin, jonka parametrien määrä täsmää metodikutsun kanssa (siis lähdettäessä alaluokasta kohti java.lang.object -luokkaa). Sanotaan, että olemme ylikirjoittaneet luokasta omena periytyneen  tulostaAttribuutit() -metodin luokassa soseOmena. Yleisesti ottaen mikä tahansa metodi voidaan ylikirjoittaa, ellei muuntimella ole metodia muutettu kappaleessa 8.5.1.2 mainituin rajoituksin. Tällä tarkoitetaan final ja static muuntimella varustettuja metodeja. Niitä ei siis voi ylikirjoittaa.

8.6.1 Muodostimen ylikirjoittaminen

Java ei periaatteessa salli muodostimen ylikirjoittamista. Tämähän ei ole periaatteessa mahdollista, koska muodostimen nimi on sama kuin mitä luokalla on ja jokaisella luokalla on oltava toisistaan poikkeava nimitys. Itseasiassa esimerkissa E43 kutsuttiin muodostinta luokassa soseOmena. Koska soseOmena periytyy luokasta omena, kutsutaan samalla kertaa myös luokan omena muodostinta ja niin edelleen aina luokan Java.lang.object -luokan muodostimeen asti. Tämä kaikki tapahtuu automaattisesti, joten jokaisessa luokassa, mitä aiotan periyttää olisi hyvä olla muodostin ylikuormitettu ainakin sellaisella muodostimella, jolla ei ole lainkaan muodollisia parametreja.

8.6.2 super -muuttuja

Esimerkin E43 soseOmena -luokan muodostimessa halutaan eksplisiittisesti kutsua luokan Omena muodostinta seuraavasti

class soseOmena extends omena {
  boolean soseena=false;
  public soseOmena(String vari1, String maku1, boolean matoisuus1, boolean soseena1) {
    new omena(vari1,maku1,matoisuus1) //Tämä ei toimi
    soseena = soseena1;
  }
}

New komento loisi uuden olion ja sitähän ei haluta tehdä. Toisaalta muodostinta ei voida kutsua erikseen. Pulma ratkeaa muuttujalla super, joka viittaa olion kantaluokan muuttujaan tai metodiin. Sitä voi käyttää esimerkiksi seuraavalla tavalla.

class soseOmena extends omena {
  boolean soseena=false;
  public soseOmena(String vari1, String maku1, boolean matoisuus1, boolean soseena1) {
    super(vari1,maku1,matoisuus1) //asetetaan arvot muuttujiin vari, maku, matoisuus;
    soseena = soseena1;
    super.asetaVari(vari1); // tämä on vain malliksi
    super.vari = vari1; //super on tässä turha. vari on määritelty public -muodostimella !
  }
}

super ja this muuttujat liittyvät ylikirjoitettuihin metodeihin tai saman nimisiin jäsenmuuttujiin. this viittaa alaluokassa olevaan ja super kantaluokassa olevaan metodiin tai jäsenmuuttujaan

Seuraavassa esimerkissä 46 on periytetty esimerkin 45 luokka, ylikirjoitettu tulosta metodi ja käytetty this ja super -muuttujia (toivottavasti) havainnollisella tavalla

Esimerkki 46

Luokka tulostaLuokka oli seuraavanlainen

class tulostaLuokka {
  int  x = 0,  y = 1;
  void tulosta() {
    System.out.println("x on "+x+" y on "+y);
     System.out.println("Tämä on luokan " + this.getClass().getName() + " olio");
  }
}

Seuraavaksi tehdään luokka E46 joka periytyy luokasta tulostaLuokka ja ylikirjoitetaan metodi tulosta()

class E46 extends tulostaLuokka {
   int  z=3;
   void tulosta() {
     System.out.println(" x= "+x+" y= "+y+" z= "+z);
     System.out.println("Tämä on luokan " + this.getClass().getName() + " olio");
   }
  public static void main(String args[]){
    E46 olio = new E46();
    olio.tulosta();
   }
}

Tulostuksena saadaan

x=0 y=1 z=3
Tämä on luokan E46 olio

Jos halutaan käyttää alkuperäistä luokan tulostaLuokka metodia tulosta, menetellään seuraavasti

class E46 extends tulostaLuokka {
   z=3;
   void tulosta() {
     super.tulosta();   //kantaluokan tulostusmetodi
     System.out.println(" z= "+z);
     System.out.println("Tämäkin on luokan " + this.getClass().getName() + " olio");
   }
  public static void main(String args[]){
    E46 olio = new E46();
    olio.tulosta();
   }
}

Tehtäviä

  1. Ylikirjoita luokkaan petokala jokin luokan kala metodi. Tee ohjelma T86, jossa käytät luokkaa petokala siten, että selvästi näet käytettävän ylikirjoitetun metodin vaikutuksen.

    Vastaus

Ilkka Koivistoinen 13.02.2002

Edellinen

Seuraava