Poziom.DCzęść NR.11

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.

private protected

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.