Míg egy Java osztály hozzáférhetőségének két szintje van (public és default), az osztály tagjainak (változók, metódusok) négy : public, protected, default és private. A default vagy más néven csomag-szint az, amikor nem írunk semmit a tag elé.
Az osztály-tagok hozzáférhetősége azt jelenti, hogy egy kódrészlet meghívhatja a metódust, megváltoztathatja/kiolvashatja a változót.
Ehhez természetesen az adott kódrészletnek hozzá kell férnie az osztályhoz. Tehát ha a szóban forgó kódrészlet "nem látja" az osztályt, akkor nem fogja tudni meghívni a metódusát sem. Ezért ebben a cikkben mindig feltételezem, hogy a vizsgált osztály látható.
A hozzáférést szabályozó szót a tag elé kell írni. Nézzük a szinteket:
public a tag látható bárki számára
private a tag csak a saját osztálya számára látható
[default] a tag csomagjából látható
protected mint a default, plussz még alosztályokban látható a tag (örökölhető)
Nézzünk példákat
Legyen a kiinduló osztályunk ilyen:
1 package p;
2 public class A {
3 private void aPrivate(){}
4 void aDefault(){}
5 protected void aProtected(){}
6 public void aPublic(){}
7
8 public void test(){
9 aPrivate();
10 aDefault();
11 aProtected();
12 aPublic();
13 }
14 }
Az a betűvel kezdődő metódusok láthatóságát nézzük meg, különböző programkódokból.
Láthatóság az osztályon belül
A fordító nem jelez hibát, azaz a test metódusból mindent elérünk, ami az A osztályhoz tartozik. Nincs ezen semmi meglepő, ez a természetes. Egy osztályba olyan metódusokat teszünk, amik nagyon szorosan kapcsolódnak egymáshoz, nem "dugdossuk" ezeket egymás elől.
Láthatóság csomagon belül
1 package p;
2 public class Test {
3 public Test(){
4 A a = new A();
5 a.aPrivate();
6 a.aDefault();
7 a.aProtected();
8 a.aPublic();
9 }
10 }
A Test osztály szintén a "p" csomagban van. A 4. sorban létrehozott "a" objektum metódusainak láthatóságát teszteljük:
Melyik sor(ok)ban jelez hibát a fordító?
A 8. sor nyilván jó, public metódussal nem lehet probléma. A default és a protected szintek megengedik a saját csomagból való elérést. Private tagot viszont csak saját osztályból érhetünk el, azaz csak az A osztályból lehetne meghívni az aPrivate metódust.
Láthatóság csomagon kívülről, örökléssel
1 package q;
2 import p.A;
3 class ExtendTest extends A {
4 public ExtendTest(){
5 ExtendTest e = new ExtendTest();
6 a.aPrivate();
7 e.aDefault();
8 e.aProtected();
9 e.aPublic();
10 }
11 }
A "q" csomagban levő ExtendTest osztály kiterjeszti az A osztályt, ami a "p" csomagban van. Az 5. sorban létrehozunk egy példányt az ExtendTest osztályból, ami az A osztály egy alosztálya, tehát öröklés útján megkapjuk az A osztály bizonyos tagjait. De vajon melyeket?
Melyik sor(ok)ban jelez hibát a fordító?
A 9. sor nyilván jó, public metódussal nem lehet probléma. A default szint csak a saját csomagból való elérést engedi. A protected példányosítással szintén csak a saját csomagjából érhető el vagy öröklés útján. Private tag már az előző pédánál is kiesett...
Láthatóság csomagon kívülről, példányosítással
1 package q;
2 import p.A;
3 public class Test {
4 public Test(){
5 A a = new A();
6 a.aPrivate();
7 a.aDefault();
8 a.aProtected();
9 a.aPublic();
10 }
11 }
A Test osztály a "q" csomagban van, míg a vizsgált A osztály a "p" csomagban. Az 5. sorban létrehozunk egy példányt az A osztályból.
Melyik sor(ok)ban jelez hibát a fordító?
A default és a protected szintek csak a saját csomagból való elérést engedik meg (példányosítással).
Van még néhány érdekes téma a hozzáférésekkel kpcsolatban. Remélem, elő fognak jönni a hozzászólásokban. Ha nem, akkor kifejtem egy következő cikkben.