Poziomy dostępu deklarują na jakim poziomie dany element klasy bądź sama klasa jest widoczna.
W Javie mamy 4 typy dostępu. Są one następujące: public, protected, private i private na poziomie paczki.
Ten ostatni poziom nie może być jawnie zadeklarowany za pomocą słowa kluczowego.
Warto zaznaczyć, że poziom dostępu protected daje dostęp do wszystkich klas w danej paczce, nawet jeśli one nie dziedziczą po tej klasie.
public int myPublic; // dostępny wszędzie
protected int myProtected;// na poziomie paczki lub klasy pochodnej
int myPackage; // na poziomie paczki
private int myPrivate; // na poziomie klasy
Kiedyś w Javie istniał dostęp private proteced, który pozwalał udostępniać elementy tylko klasom dziedziczącym, ale obecnie go nie ma.
Domyślny poziom w Javie to nieokreślony słowem kluczowym poziom paczki.
W C# mamy 5 typów dostępu:
- public, = wszędzie dostępny
- protected, = dostępny na poziomie klasy lub klasy pochodnej
- internal, = dostępny na poziomie biblioteki
- protected internal, = dostępny na poziomie klasy lub klasy pochodnej lub wewnątrz biblioteki
- private. = dostępny tylko dla klasy
Domyślnym poziom dla klasy w C# to poziom private.
Private C# i Java
Klasa może uzyskać dostęp do wszystkich swoich elementów.
class Klaska
{
// dostępny wszędzie
public int myPublic;
// dostępny na poziomie biblioteki
protected internal int myProtInt;
// na poziomie biblioteki
internal int myInternal;
// na poziomie klasy lub klasy pochodznej
protected int myProtected;
// tylko dla klasy
private int myPrivate;
void DoIt()
{
myPublic = 0; // ok
myProtInt = 0; // ok
myInternal = 0; // ok
myProtected = 0; // ok
myPrivate = 0; // ok
}
}
W javie jest podobnie
package paczusia;
public class Klaska
{
public int myPublic;
protected int myProtected;
int myPackage;
private int myPrivate;
void doIt()
{
myPublic = 0; // ok
myProtected = 0; // ok
myPackage = 0; // ok
myPrivate = 0; // ok
}
}
Na poziomie paczki : Java tylko
Wewnątrz paczki masz dostęp do wszystkiego z wyjątkiem elementów na poziomie private.
package paczusia;
public class InnaKlaska
{
void test(Klaska m)
{
m.myPublic = 0; // ok
m.myProtected = 0; // ok
m.myPackage = 0; // ok
m.myPrivate = 0; // nie dostępne
}
}
lnternal na poziomie biblioteki : tylko C#
Na poziomie biblioteki wszystkie elementy są dostępne poza tymi, które wymagają dziedziczenia czyli protected oraz są prywatne.
Inna biblioteka jednak nie uzyska dostępu do elementu internal.
// Wewnątrz biblioteki
class InnaKlaska
{
void DoIt(Klaska m)
{
m.myPublic = 0; // ok
m.myProtInt = 0; // ok
m.myInternal = 0; // ok
m.myProtected = 0; // brak dostępu
m.myPrivate = 0; // brak dostępu
}
}
Protected C#
Poziom protected udostępnia element dla klasy pochodnej i poza tym działa jak poziom private.
class PochodnaKlasy : Klaska
{
void DoIt()
{
myPublic = 0; // ok
myProtInt = 0; // ok
myInternal = 0; // ok
myProtected = 0; // ok
myPrivate = 0; // brak dostępu
}
}
Protected Java
Elementy protected w Javie są dostępne w obrębie paczki i klasy pochodnej oraz samej klasy.
Oznaczenie protected ma inny poziom niż w innych językach jak np. C#.
package nowaPaczusia;
import paczusia.Klaska;
public class PochodnaKlaska extends Klaska
{
void doIt()
{
myPublic = 0; // ok
myProtected = 0; // ok
myPackage = 0; // brak dostępu
myPrivate = 0; // brak dostępu
}
}
Protected Internal C#
Poziom protected Javy można przybliżyć do poziomu protected Internal w C#.
Ten poziom oznacza, że dany element ma kombinację dwóch poziomów dostępu : protected i internal.
Element jest więc dostępny dla klas pochodnych oraz dla wszystkich klas wewnątrz swojej biblioteki.
// Inna biblioteka
class PochodnaKlasa : Klaska
{
void DoIt(MyBase m)
{
m.myPublic = 0; // ok
m.myProtInt = 0; // ok
m.myInternal = 0; // brak dostępu
m.myProtected = 0; // ok
m.myPrivate = 0; // brak dostępu
}
}
Poziom public : Java i C#
Dany element jest dostępny wszędzie
// Inna biblioteka
class InnaKlasa
{
void DoIt(Klaska m)
{
m.myPublic = 0; // ok
m.myProtInt = 0; // brak dostępu
m.myInternal = 0; // brak dostępu
m.myProtected = 0; // brak dostępu
m.myPrivate = 0; // brak dostępu
}
}
package nowapaczka
import paczusia.Klaska;
public class InnaKlasa
{
void doIt(Klaska m)
{
m.myPublic = 0; // ok
m.myProtected = 0; // brak dostępu
m.myPackage = 0; // brak dostępu
m.myPrivate = 0; // brak dostępu
}
}
Poziom samej klasy a jej elementy
Co z tego jeśli elementy klasy są publiczne, jeśli sama klasa nie jest publiczna.
Nie można utworzyć prywatnej klasy bo to mijałoby się z celem. Można jednak określić, czy dana klasa jest na poziomie paczki/biblioteki.
A to też dotyczy jej elementów.
// dostępny tylko dla paczki
class PackagePrivateClass {}
// dostępny dla każdego
public class PublicClass {}
;
internal class MyInternalClass {}
public class MyPublicClass {}
Klasy zagnieżdżone
Java jak i C# pozwalają na zagnieżdżanie klas.
Ich poziom deklaracji jest identyczny do poziomu innych elementów klas, jak metody czy pola.
Klasa zagnieżdżona z poziomem private jest dostępna tylko dla klasy głównej.
class MajorClass
{
// klasy zagnieżdżone, klasy wewnętrzne
public class MyPublic {}
protected internal class MyProtInt {}
internal class MyInternal {}
protected class MyProtected {}
private class MyPrivate {}
}
Jaki poziom dostępu wybierać
Zalecane jest używanie jak najbardziej restrykcyjnego poziom dostępu. Gdy element jest dostępny w wielu miejscach oznacza to, że w wielu miejscach może on zostać użyty źle.
Poziomy dostępu mają nam ułatwić modyfikowanie mechanizmów klasy bez zmieniania kodu w innych klasach.
Jest to zasada hermetyzacji.