Gyakorlati alapok III.
A hozzáférés-módosítók
A hozzáférés-módosítás a kód valamelyik szegmenséhez való hozzáférés korlátozását jelenti, amely legtöbbször a futtathatóságban mutatkozik meg, bár az Eclipse magas szintű hibaanalízise miatt ezt sokszor fordítási hiba előzi meg.
Alapszintű hozzáférés-korlátozással eddig is találkozhattunk: lokálisan deklarált változókhoz nem tudtunk hozzáférni magasabb szintről, azaz saját blokkjukon kívül. Adott például egy for ciklus, amelyet legtöbbször egy belső változó műveltet (iterátor), ennek szabványos deklarálása általában int i. Ehhez a változóhoz nem tudunk hozzáférni saját blokkján kívül (System.out.println(i);):
public class
Main {
public static void main(String[] args) {
for(int i = 0; i < 3; i++){
System.out.println("Helló!");
}
System.out.println(i);
}
}
Végeredmény:
fordítási hiba
Vagy azonos osztályban (itt Main) lévő egyik metódus (itt main()) nem tud hozzáférni a másik, külső metódus változójához (int valtozo = 10;):
public class
Main {
static void valtozoTarolo(){
int valtozo = 10;
}
public static void main(String[] args) {
System.out.println(valtozo);
}
}
Végeredmény:
fordítási hiba
Ilyen jellegű lokális hozzáférés-korlátozás a kódszegmensek között alapértelmezett nemcsak a Javában, hanem a hasonló bonyolultságú és szintű nyelvekben is.
Mivel a Java-nyelvben már a kezdetektől fogva nagy hangsúlyt helyeztek a biztonságra, illetve az objektumorientált szemlélet kialakította az osztályok és tárolóegységeik, a csomagok (package) összehangolt működését, ezért további, magasabb, már osztályszinten működő hozzáférés-módosítások (access modifiers) is beépítésre kerültek. Itt kell azonban megjegyeznünk, hogy ezek nemcsak osztályok, hanem ugyanolyan funkcióval az osztályok közti csatlakozási felületek (interfész - interface) hozzáférését is szabályozzák. Az utóbbiakról később lesz szó.
Mivel a probléma megértése nehéz, rögtön ugorjunk bele egy újabb példába!
Default - csomagszintű hozzáférés
Adott 2 tárolóegység (csomag - package), amely 2 osztályt (class) tárol:
package Miniszterium;
class Iskolafelügyelo;
package Iskola;
class Tanar;
Alapértelmezésben a 2, különálló csomagban deklarált 2 osztály nem látja egymást, azaz egyik sem tud hozzáférni a másik változóihoz, metódusaihoz. Ez az úgynevezett alapértelmezett (default), azaz csomagszintű hozzáférés. Ez már önálló hozzáférés-módosítás, de mivel ez az alapértelmezett, nincsen külön szójelölése. (A Java-vizsgák jellegzetes beugratós kérdése ez.)
Public - nyilvános hozzáférés
Ez a legkevésbé korlátozott hozzáférés: az osztály gyakorlatilag publikussá, ezáltal elérhetővé, felhasználhatóvá teszi önnön változóit, metódusait.
Az Iskola csomag importálása és a Tanar osztály példányosítása után annak összes változója és metódusa bárhonnan szabadon elérhető.
Protected - védett hozzáférés
Ez a hozzáférés-módosító a következő kódhelyzetekben ad szabad hozzáférést az osztályokhoz (és interfészekhez):
-
azonos csomagban deklarált osztályok (és interfészek) esetében,
-
az ősosztályból öröklődéssel létrehozott (származtatott - derived) utódosztályok esetében, még ha azok külön csomagban is találhatók.
Öröklődésről még nem volt szó idáig a honlapon, ezért a téma kifejtését a későbbiekben tesszük meg.
Private - magán hozzáférés
A legszigorúbb hozzáférés-korlátozást jelenti. Ezzel a kulcsszóval az osztály önmagába zárja saját változóit és metódusait, azaz külvilág elől teljesen elrejti.
Foglaljuk tehát össze:
-
default,
-
public,
-
protected,
-
private.
Ezek a fő, osztályszintű hozzáférés-módosítók, ám ha jobban belegondolunk, a lokális változó elérhetőségein felül már foglalkoztunk olyan lehetőségekkel, amelyek valamilyen módon szintén befolyásolják a kódelérést vagy kódfuttathatóságot. Ezek inkább a hozzáférés jellegét módosítják. 2 ilyen, már tárgyalt módosító:
A static és final módosítókon felül a Java-nyelvben további, hasonló jellegű hozzáférés-korlátozók is rendelkezésre állnak, ezeket összefoglaló nevükön nonaccess modifiers szavakkal rendszerezzük. A legfontosabbak:
-
abstract (osztály, interfész, metódus) - nem példányosítható vagy példányosítása nem értelmezhető (interfész). Az osztályok és metódusok esetében később lesz kifejtve. (Abstract osztály - abstract metódus című fejezet)
-
synchronized (metódus) - többszálú kódfutás (multiple threads) esetén tiltja, hogy a metódust azonos időben egyszerre több szál futtassa, módosítsa. Nem használható osztályok, interfészek, változók esetében. (A synchronized kulcsszó című fejezet)
-
native (metódus) - felhasználhat más nyelvekben (C vagy C++) implementált kódot. Nem használható osztályok, interfészek, változók esetében.
-
transient (változó) - ezzel a szóval illetett változó nem lesz szerializálva, míg szerializált objektum összes változója igen. Nem használható osztályok, interfészek, metódusok esetében. (A szerializálás a Bemenet - Kimenet című fejezetcsomagban lesz részletesen kifejtve.)
-
volatile (változó) - Olyan változó, amelyet egyszerre több szál is felhasználhat, módosíthat. Nem használható osztályok, interfészek, metódusok esetében. (A volatile kulcsszó című fejezet)
-
strictfp (osztály, interfész, metódus) - lehetővé teszi, hogy a lebegőpontos számítások minden platformon ugyanazt az eredményt szolgáltassák. Nem használható változók esetében.