Ściąga z modyfikatorów dostępu

2009-10-16 16:08

W prawie wszystkich językach obiektowych istnieją tak zwane specyfikatory dostępu, przykładem których jest choćby public czy private. Pozwalają one ustalać, jak szeroko dostępne są poszczególne składniki klas w stosunku do reszty kodu. Modyfikatory te występują m.in. w trzech najpopularniejszych, kompilowalnych językach obiektowych: C++, C# i Javie.

Problem polega na tym, że w każdym z nich działają one inaczej. Mało tego: każdy z tych języków posiada inny zbiór tego rodzaju modyfikatorów. Dla kogoś, komu zdarza się pisać regularnie w przynajmniej dwóch spośród nich, może to być przyczyną pomyłek i nieporozumień.
Dlatego też przygotowałem prostą ściągawkę w postaci tabelki, którą prezentuję poniżej. Symbol języka występujący w komórce oznacza tutaj, że dany modyfikator (z wiersza) powoduje widoczność składnika klasy w określonym miejscu (z kolumny).

Specyfikator Klasa Podklasa Pakiet Reszta
public C++ C# Java C++ C# Java C# Java C++ C# Java
protected C++ C# Java C++ C# Java Java
protected internal C# C# C#
internal C# Java C# Java
private C++ C# Java

Parę uwag gwoli ścisłości:

  • Znaczek C++ nie występuje w kolumnie Pakiet nawet dla modyfikatora public, jako że w tym języku w ogóle nie istnieje pojęcie pakietu.
  • Sam termin ‘pakiet’ jest poza tym właściwy dla Javy. W .NET (C#) jego odpowiednikiem jest assembly, jakby ktoś nie wiedział :)
  • Z kolei internal jest słowem specyficznym dla C#, a jego ekwiwalentem w Javie jest po prostu pominięcie modyfikatora w deklaracji (np. int x; zamiast internal int x;).
  • W końcu, protected internal jest modyfikatorem występującym wyłącznie w C#/.NET.
Tags: , , , , , ,
Author: Xion, posted under Programming »


10 comments for post “Ściąga z modyfikatorów dostępu”.
  1. Dabroz:
    October 16th, 2009 o 19:23

    “Znaczek C++ nie występuje w kolumnie Pakiet nawet dla modyfikatora public, jako że w tym języku w ogóle nie istnieje pojęcie pakietu.”

    Nie zgodzę się. W C++ mamy pojęcie jednostki kompilacji i “specyfikator” dla niej (static bądź namespace{}). Oczywiście ów “specyfikator” nie może dotyczyć metod klas, a jedynie zwykłych funkcji.

  2. Xion:
    October 16th, 2009 o 20:08

    Nie jest to jednak pakiet w sensie Javy/.NET/Pythona/etc., bo nie jest:

    – deklaratywny (wynika tylko z fizycznego umieszczenia pewnych elementów w danym pliku, a nie z jawnego napisania że X należy do pakietu Y)
    – rozszerzalny
    – hermetyzowalny w sensie OOP-u (jest tylko możliwość ukrycia elementów w static/namespace{} przez innymi jednostkami translacji; nie da się chociażby ukryć jakiegoś elementu przez resztą takiego “pakietu” ani mieć bardziej skomplikowanych przypadków jak te przedstawione wyżej)

  3. Kos:
    October 17th, 2009 o 21:37

    A D? A gdzie jest D? ^^

    Gdybyś i Ty zechciał wesprzeć Propagandę Lepszego Jutra i uzupełnić notkę, odpowiedni fragment specyfikacji jest tutaj, pod nagłówkiem “Protection attribute”:
    http://www.digitalmars.com/d/1.0/attribute.html

    W skrócie:

    private – klasa, moduł
    package – klasa, moduł, pakiet (vide ‘internal’)
    protected – klasa, moduł, podklasa
    public – klasa, podklasa, pakiet, reszta

    (Jest jeszcze krok dalej od public, w postaci ‘export’ – z myślą o bibliotekach).

    Uwagi na marginesie:

    a) D ma moduły i pakiety, ale nie ma tam jak w Javie, że “1 moduł = 1 klasa publiczna”. Moduł może mieć cokolwiek: kilka klas, funkcje i zmienne globalne. Dlatego dodatkowo wyróżniamy widoczność w module (która nota bene istnieje zawsze :)).

    b) “Zwykłe” zmienne i funkcje w module mogą również mieć atrybut private, package, public lub export; działanie j.w. Moduł generalnie w D przypomina w wielu miejscach klasę statyczną.

  4. Force:
    October 17th, 2009 o 23:37

    To ja w takim razie stanę w obronie Delphi, które tez jest przecież bardzo popularne, i nie wiem czy bardziej niż C# :D Też ma moduły, w każdym może być wiele klas, mogą one nawet być całe prywatne (widoczne tylko w danym module) gdy ich definicja jest w “implementation”. Public (oraz Published) i Protected są jak w javie. Private powoduje, że element jest widoczny w klasie i pakiecie (ale nie podklasach), czyli działa jak “internal”. Strict private działa jak jak private w javie czyli tylko w klasie widać. Strict protected działa jak protected z C# (czyli klasa i podklasa). Słowo “strict” przed “private” i “protected” powoduje, że elementy nie są widoczne w tym samym module, same “private” i “protected” powoduje, że są widoczne w module. Fioletowy dla Delphi w tabelce ? :D

  5. Xion:
    October 18th, 2009 o 1:13

    Dzięki za uzupełnienia odnośnie innych języków. W tabelce zamieściłem te trzy głównie dlatego, że sam je dobrze znam/używam, a i – tak jak napisałem w notce – są to najpopularniejsze, kompilowalne języki obiektowe według TIOBE z października:

    http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

    Jak widać Delphi i D trzymają się tam dość kiepsko :) Oczywiście można dodać je do tabelki, ale wtedy jej rozmiary rozdęłyby się niepomiernie.

  6. Alton:
    October 18th, 2009 o 9:52

    Może na świecie, ale wydaje mi się, że w Polsce Delphi ma się lepiej albo co najmniej tak samo jak C#. A tę notkę piszesz przecież po polsku, więc powinna być dla Polski sprofilowana ;)

  7. Force:
    October 20th, 2009 o 18:36

    Wg mnie powinno się dodać Delphi, w Polsce jest popularne bo dużo osób używa, ale też niepopularne bo Ci co nie piszą w nim nic o nim nie wiedza (o c++ ludzie wiedzą) co wynika z myśli “Delphi to jak Pascal). Sam fakt, że są klasy jest szokiem dla nich, a co dopiero fakt, że jest 5 zakresów widzialności (published to jak public). To byłby to szokujący post walczący z ciemnogrodem :D

  8. Alton:
    October 21st, 2009 o 18:22

    Leciutko zboczę z tematu, ale w ogóle uważam, że ludzie nie używają Delphi bo sobie wmówili, że to z Pascala się wywodzi, a to nie jest “tru”, bo zamiast uroczych nawiasów klamrowych mamy jakieś długie begin…end i w ogóle kod taki rozwlekły. A następnie wracają do swojego ukochanego C++ i zaczynają się głowić, o czym myśleli tydzień temu tworząc taki oto warunek:

    while(*a++=*b++);

    Wbrew pozorom ta pętelka nie jest taka głupia, bo po dodaniu deklaracji zmiennych dostalibyśmy coś co działa identycznie jak pewna funkcja z biblioteki standardowej C :D

  9. Aithne:
    October 22nd, 2009 o 22:23

    Ktoś ci każe w taki sposób pisać? Można zrobić normalnie wyglądającą pętlę, z czytelnym warunkiem i ciałem, albo jeszcze lepiej – użyć strcpy. Możliwość napisania nieczytelnego kodu to nie jest wada języka.

  10. Radoslaw Szulgo:
    February 17th, 2010 o 23:28

    W Javie nie ma zdaje sie dostepu “internal” . Mozna go conajwyzej eumulowac.

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.