Kihagyás

11. gyakorlat

A gyakorlat anyaga

Belső osztály

Mennyire jó lenne, ha egy csordának nem kellene megmondanunk az elemszámát, hanem attól függően, hogy hány elemet rakok bele, változna a mérete. A jó hír, hogy ezt megtehetjük, emlékezzünk vissza a Programozás alapjai kurzuson tanultakra, volt "valami" láncolt lista megvalósítás. Igaz, ott C-ben dolgoztunk, de azért az ott tanultakat jó eséllyel itt is el tudjuk sütni, de ehhez szükségünk lesz egy új osztályra, például LancElem néven.

Azonban érdemes kicsit gondolkozni rajta, hiszen ezt az osztályt nem szeretnénk a nyilvánosság elé tárni, sőt igazából gyakorlati jelentősége nincs, hogy a Csorda milyen módon tárolja az csordában lévő állatokat. Milyen jó lenne, ha megoldható lenne az, hogy van egy osztályunk, és azt csak a Csorda osztály számára tesszük láthatóvá. Osztályok láthatósága public vagy package-private (kulcsszó nélkül) lehet, úgyhogy erre nincs lehetőségünk alapvetően. Ami a jó hír, hogy nem ezen a módon, de mégis megtehetjük ezt, azaz készíthetünk egy osztályt, amelyet csak egy másik osztály lát. Ehhez egy belső osztályt kell készítenünk, a fenti LancElem néven.

Lehetőségünk van osztályon belül, vagy akár metóduson belül deklarálni osztályokat. Ezek a "hagyományos "osztályokkal ellentétben lehetnek private, protected láthatóságúak is (a "hagyományos" osztályok láthatósága csak public vagy package-private lehet). Sőt, a belső osztályokat elláthatunk static módosítószóval is.

A belső osztályok hozzáférnek a külső osztály adattagjaihoz, metódusaihoz. Ez alól kivétel, ha a belső osztály statikus. Ez a kulcsszó jelen helyzetben gyakorlatilag annyit jelent, hogy a belső és külső osztálynak nincs köze egymáshoz.

A belső osztályok célja, hogy egy osztályon belül elrejtsünk egy máshol nem használt adatszerkezetet, algoritmust, ugyanakkor ezeket akár kívülről is elérhetjük (ha úgy állítjuk be a láthatóságukat). Az osztályon belül egyszerűen, a tanult módon példányosítjuk őket, azonban akár kívülről is megtehetjük ezt.

Példányosítás, ha a belső osztály nem statikus láthatóságú:

class Kulso {
   private int num = 175;

   public class Belso {
      public int getNum() {
         System.out.println("Visszaterunk a szammal.");
         return num;
      }
   }
}

public class MainOsztaly {

   public static void main(String args[]) {
      Kulso kulsoPeldany = new Kulso();
      // Nem statikus belso osztaly
      Kulso.Belso belsoPeldany = kulsoPeldany.new Belso();
      System.out.println(belsoPeldany.getNum());
   }
}

Példányosítás, ha a belső osztály statikus láthatóságú:

class Kulso {
   static class Belso {
      public void print() {
         System.out.println("Belso osztaly kiiratasa");
      }
   }
}

public class MainOsztaly {

   public static void main(String args[]) {
      Kulso.Belso belsoPeldany = new Kulso.Belso();
      belsoPeldany.print();
   }
}

Ezek ismeretében valósítsuk meg a belső LancElem osztályt, a Csorda osztályon belül. Mivel ezt máshol nem szeretnénk használni, nyugodtan tegyük privát láthatóságúvá. Ezt követően írjuk át a Csorda osztály, hogy az eddig használt statikus tömb helyett a saját láncolt lista megvalósításunkat használjuk!

public class Csorda {
    private class LancElem {
        public Allat tag;
        public LancElem kov = null;

        public LancElem(Allat tag, LancElem kov) {
            this.tag = tag;
            this.kov = kov;
        }
    }

    // Tömb helyett csak a lánc fejét tároljuk
    private LancElem fej;
    private int jelenlegi;

    private boolean szarazfoldiAllatok;

    public Csorda() {
        this.jelenlegi = 0;
        this.fej = null;
    }

    public boolean csordabaFogad(Allat kit) throws InkompatibilisAllatok {
        if (jelenlegi == 0) {
            if (kit instanceof SzarazfoldiAllat) {
                szarazfoldiAllatok = true;
            }
        }
        if ( (szarazfoldiAllatok && kit instanceof ViziAllat) ||
             (!szarazfoldiAllatok && kit instanceof SzarazfoldiAllat)) {
            throw new InkompatibilisAllatok();
        } else {
            LancElem tmp = new LancElem(kit, this.fej);
            this.fej = tmp;
            jelenlegi++;
            return true;
        }
    }

    public String toString() {
        String returnValue = "Allatok: ";
        LancElem jelenlegi = fej;
        while (jelenlegi != null) {
            returnValue += jelenlegi.tag.getNev();
            returnValue += ", ";
            jelenlegi = jelenlegi.kov;
        }
        return returnValue;
    }
}

Lambda kifejezések


Utolsó frissítés: 2024-04-11 07:54:27