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?
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?
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!
a konstruktor, reális az, hogy valaki létre akar hozni egy példány italt? Gondolnánk, hogy igen, de senki sem fog egy 5 decis 4%-os Innivalót csak úgy létrehozni most, mert ez egy kocsma, nem pedig szeszfőzde. Itt kész italokkal, Sörrel, Borral dolgozunk. Szóval inkább ne hozzon létre senki Innivalót, kivéve az Innivaló leszármazottak, tehát a Sör, a Bor az igen. Ezért ez protected - tehát a leszármazottak láthatják, de a nagyvilág nem.
reális, hogy a nagyvilágból valaki meg akarja hívni a toStringet? Igen, ezért ez public (mint ahogy eredetileg is public volt)
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:
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!