06-Igényes programkód

Eddig azért elég messzire eljutottunk. Most nézzük meg, hogy mi az a pici különbség, amit a profik másként csinálnak! Semmi nehézre nem kell gondolni, hiszen Te is elkezdtél már úgy gondolkodni, mint egy profi. A profiknak csak annyi az előnye, hogy még ismernek pár módszert arra, hogy még megbízhatóbb legyen a program.

Mitől nem megbízható egy program? A programnak két ellensége van:

Jelen esetben a második gond a nagyobb. Például,a Kocsma példa esetén senki sem akadályoz meg minket abban, hogy erős hipnózissal a Kocsma elhitesse Jack-el, hogy nem is ivott még semmit:

public class Kocsma {

    public static void main(String[] args) {
        Pultos feri=new Pultos();

        Ember jack=new Ember("Jack",1.2);
        jack.igyal(feri.adjEgyet());

        jack.fogyasztottAlkohol=0; // !!!

        System.out.println(jack);
    }
}
Jack megivott 0.5 deci italt, össz. 0.0 deci alkohol tartalom.
  Törkölypálinka, 0.5 deci, 40.0%

Simán végrehajtódott ez, hiszen szintaktikailag helyes, de szemantikailag helytelen. Magyarul értelmes, de ellentmond a valóságnak: nem lenne szabad, hogy bárki állítgassa Jack alkoholszintjét. Az meg kifejezetten fura, hogy egyszer kiírjuk, hogy pálinkát ivott, de azárt mégsem fogyasztott alkoholt pálinkát? Mi volt ez akkor?

Obi van Kenobi épp Jack alkoholszintjét hipnotizálja

Ez butaság, ilyen nem lehet! Na most, azért, hogy ilyen hibát ne kövessünk el, két dolgot tehetünk:

Nyilván a második megoldás kissé biztonságosabb, ugye?

A láthatóság (visibility)

Ez a dolog azt jelenti, hogy pontosan beállítjuk, hogy egy osztályban a tulajdonságokat (változókat) és a metódusokat ki láthatja, és használhatja. Persze nem névsort kell megadni, csak az alábbi pár lehetőségünk van:

A feladat tehát: el kell dönteni, hogy egy Innivalo-ban mi milyen legyen?

public class Innivalo {
    double felszolgaltMeret=5; // dl
    double alkoholTartalomSzazalek=4; // %
    String nev;


    Innivalo(String nev,double felszolgaltMeret,double alkoholTartalomSzazalek) {
        this.nev=nev;
        this.felszolgaltMeret=felszolgaltMeret;
        this.alkoholTartalomSzazalek=alkoholTartalomSzazalek;
    }

    public String toString() {
        return nev+", "+felszolgaltMeret+" deci, "+alkoholTartalomSzazalek+"%";
    }
}

A toString az el van döntve, annak olyannak kell lennie mint a megöröklött toString, amit override-olunk (felülbírálunk), tehát az public.

Mi legyen a tulajdonságokkal? Ha ezeket a tulajdonságokat kívülről menet közben nem ér állítani, akkor private. Kérdezzük meg magunktól:

Lássuk a metódusokat!

No és akkor az egész osztály? Az mindig public class, hisz olyan osztálynak amit senki sem láthat és használhat, nincs sok értelme.

public class Innivalo {
    private double felszolgaltMeret=5; // dl
    private double alkoholTartalomSzazalek=4; // %
    private String nev;


    protected Innivalo(String nev,double felszolgaltMeret,double alkoholTartalomSzazalek) {
        this.nev=nev;
        this.felszolgaltMeret=felszolgaltMeret;
        this.alkoholTartalomSzazalek=alkoholTartalomSzazalek;
    }

    public String toString() {
        return nev+", "+felszolgaltMeret+" deci, "+alkoholTartalomSzazalek+"%";
    }
}

Ezek után ha esetleg megpróbálnánk a bort feljavítani, az hibás lesz:

No, most már nem lehet feljavítani a borunkat kódból!

Természetesen ha mégiscsak jó okod van arra, hogy a korábban private mezőket piszkáld, akkor ott van egy automatikus javítási lehetőség, ami láthatóbbá varázsolja a private mezőt.

Feladat: az összes osztály minden tulajdonságát és metódusát nézd át, és állítsd be a megfelelő láthatósági szintet!

A láthatósági szint a barátunk.

A láthatósági szintekkel pontosan szabályozhatjuk, hogy másoknak mit mutatunk meg az objektumunkból. Ökölszabály: minden tulajdonság private, a konstruktorok és azok a metódusok, amik a külső világ számára értelmesek, az public. Ha új osztályt származtatsz, és a leszármazottból szükséged van pár private tulajdonságra, akkor azokat állítsd át protected-re hogy a leszármazottban látható legyen.