Dlaczego atrybuty w Javie mogą być publiczne?

Jak wszyscy wiedzą, Java podąża za paradygmatami orientacji obiektu, gdzie enkapsulacja danych mówi, że pola (atrybuty) obiektu powinny być ukryte dla świata zewnętrznego i dostępne tylko za pomocą metod lub że metody są interfejsem klasy tylko dla świata zewnętrznego. Dlaczego więc możliwe jest zadeklarowanie pola w Javie jako publicznego, co byłoby sprzeczne z paradygmatem enkapsulacji danych?

Author: strauberry, 2011-12-09

12 answers

Myślę, że jest to możliwe, ponieważ każda zasada ma swój wyjątek, każda najlepsza praktyka może być uchylona w pewnych przypadkach.

Na przykład często ujawniam publiczne statyczne końcowe elementy danych jako publiczne (np. stałe). Nie sądzę, żeby to było szkodliwe.

Zwrócę uwagę, że ta sytuacja jest prawdziwa w innych językach oprócz Javy: C++, C# itp.

Języki nie zawsze muszą nas chronić przed sobą.

Na przykładzie Oli, co w tym złego, jeśli napiszę to tak sposób?

public class Point {
   public final int x;
   public final int y;

   public Point(int p, int q) {
      this.x = p;
      this.y = q;
   } 
}
Jest niezmienny i bezpieczny dla wątków. Dane mogą być publiczne, ale nie możesz ich skrzywdzić.

Poza tym, to mały brudny sekret, że "prywatne" nie jest tak naprawdę prywatne w Javie. Zawsze możesz użyć odbicia, aby go obejść.

Więc spokojnie. Nie jest tak źle.
 74
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 12:48:20

Dla elastyczności. To byłby ogromny ból, gdybym nie był w stanie napisać:

class Point {
    public int x;
    public int y;
}

Nie ma cennej przewagi, aby ukryć to za geterami i seterami.

 52
Author: Oliver Charlesworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 12:48:00

Ponieważ sztywna "enkapsulacja danych" nie jest jedynym paradygmatem, ani obowiązkową cechą orientacji obiektu.

I, bardziej do rzeczy, jeśli ktoś ma atrybut data, który ma publiczną metodę setter i publiczną metodę getter, a metody nie robią nic innego niż rzeczywiście ustawić / get atrybut, jaki jest sens utrzymywania go w tajemnicy?

 12
Author: Hot Licks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 12:49:39

Nie wszystkie klasy są zgodne z paradygmatem enkapsulacji (np. klasy fabryczne). Dla mnie Zwiększa to elastyczność. W każdym razie, to jest odpowiedzialność programisty, a nie języka, aby zakres odpowiednio.

 5
Author: mre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 12:50:04

Omawianie dobrych stron zmiennych publicznych... Podoba mi się... :)

Może być wiele powodów, dla których warto używać zmiennych public. Sprawdźmy je jeden po drugim:

Wydajność

Choć rzadko, będą pewne sytuacje, w których ma to znaczenie. W niektórych przypadkach należy unikać narzutu wywołania metody.

Stałe

Możemy używać zmiennych publicznych dla stałych, których nie można zmienić po zainicjowaniu w konstruktorze. Pomaga to również w wydajności. Czasami mogą to być stałe statyczne, jak łańcuch połączenia z bazą danych. Na przykład,

public static final String ACCEPTABLE_PUBLIC = "Acceptable public variable";

Inne Przypadki

Są przypadki, gdy public nie robi różnicy lub posiadanie gettera i settera jest niepotrzebne. Dobry przykład z Point jest już napisany jako odpowiedź.

 2
Author: Jomoos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 13:48:21

Projektowanie obiektowe nie wymaga enkapsulacji. Jest to najlepsza praktyka w językach takich jak Java, która ma znacznie więcej wspólnego z projektem języka niż OO.

To tylko najlepsza praktyka, aby zawsze enkapsulować w Javie z jednego prostego powodu. Jeśli nie zostanie zakapsulowana, nie będzie można później zakapsulować bez zmiany sygnatury obiektu. Na przykład, jeśli twój pracownik ma nazwisko, a Ty je upubliczniasz, jest to employee.name. jeśli później chcesz go zamknąć, kończysz z pracownikiem.getName () i employee.setName (). spowoduje to oczywiście złamanie dowolnego kodu przy użyciu klasy pracownika. Dlatego w Javie najlepszą praktyką jest Hermetyzowanie wszystkiego, tak aby nigdy nie trzeba było zmieniać sygnatury obiektu.

Niektóre inne języki OO (ActionScript3, C#, itd.) obsługują właściwości true, gdzie dodanie gettera / settera nie wpływa na sygnaturę. W takim przypadku, jeśli masz getter lub setter, zastępuje on właściwość publiczną tym samym podpisem, dzięki czemu możesz łatwo przełączaj się tam iz powrotem bez łamania kodu. W tych językach praktyka enkapsulacji nie jest już konieczna.

 1
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 14:07:36

Java jest gałęzią języków składniowych w stylu C. Te języki obsługiwały structs, które były stałymi aliasami offsetowymi dla bloku pamięci, który był ogólnie uważany za"jeden element". Innymi słowy, struktury danych zostały zaimplementowane za pomocą struct s.

Podczas gdy używanie struktury bezpośrednio narusza cele enkapsulacji programowania obiektowego, kiedy Java została wydana, większość ludzi była znacznie bardziej kompetentna w programowaniu iteracyjnym (proceduralnym). Odsłaniając members jako public można efektywnie używać klasy Java w taki sam sposób, w jaki można używać C struct, mimo że podstawowe implementacje obu środowisk były drastycznie różne.

Są pewne scenariusze, w których można to zrobić nawet przy odpowiedniej enkapsulacji. Na przykład wiele struktur danych składa się z węzłów zawierających dwa lub więcej wskaźników, jeden wskazuje na "zawarte" DANE, a jeden lub więcej wskazuje na "inne" połączenia z resztą struktury danych. W takim przypadku, ty może utworzyć klasę prywatną, która nie ma widoczności poza klasą "data structure" (jak Klasa wewnętrzna), a ponieważ cały kod do poruszania się po strukturze jest zawarty w tym samym pliku .java, możesz usunąć metody .getNext() klasy wewnętrznej jako optymalizację wydajności.

 1
Author: Edwin Buck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 17:19:17

Uważam, że enkapsulacja danych jest oferowana bardziej jako dodatkowa funkcja, a nie obowiązkowy wymóg lub reguła, więc koder ma swobodę korzystania ze swojej mądrości, aby zastosować funkcje i dostosować je zgodnie z ich potrzebami.Stąd elastyczne jest!

Podobny przykład może być podany przez @ Oli Charlesworth

 0
Author: samridhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 08:19:56

Jestem dopiero początkujący, ale jeśli publiczne oświadczenie nie istnieje, rozwój Javy będzie naprawdę skomplikowany do zrozumienia. Ponieważ używamy publicznych, prywatnych i innych oświadczeń, aby uprościć zrozumienie kodu, jak jars, których używamy i inni stworzyli. Chcę powiedzieć, że nie musimy wymyślać, musimy się uczyć i kontynuować.

Mam nadzieję, że po angielsku, staram się poprawić i mam nadzieję pisać jasno w przyszłości.

 0
Author: ZaoTaoBao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-14 08:24:33

Modyfikatory dostępności są implementacją koncepcji enkapsulacji w językach OO (widzę tę implementację jako sposób na rozluźnienie tej koncepcji i umożliwienie pewnej elastyczności). Istnieją czyste języki OO, które nie mają modyfikatorów dostępności, np. Smalltalk. W tym języku wszystkie stany (zmienne instancji) są prywatne, a wszystkie metody są publiczne, jedynym sposobem na modyfikowanie lub odpytywanie stanu obiektu są jego metody instancji. Brak dostępności modyfikatory metod zmuszają programistów do przyjęcia pewnych konwencji, na przykład metody w protokole prywatnym (protokoły są sposobem organizowania metod w klasie) nie powinny być używane poza klasą, ale żadna konstrukcja języka tego nie wymusi, jeśli chcesz, możesz wywoływać te metody.

 0
Author: Diego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-14 14:23:28

Używanie public czy nie tak naprawdę zależy od tego, czy istnieje niezmiennik do utrzymania. Na przykład, obiekt Pure data nie ogranicza przejścia stanu w żaden sposób, więc nie ma sensu zamykać członków kilkoma accesorami, które nie oferują więcej funkcji, które ujawniają członka danych jako publicznego.

Jeśli masz zarówno getter, jak i setter dla konkretnego Nie-prywatnego członka danych, który zapewnia nie więcej funkcji niż getting i setting, możesz chcieć zrecenzuj swój projekt lub upublicznij go.

 0
Author: Hazok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-15 06:27:25

Naprawdę nie mogę wymyślić dobrego powodu, aby nie używać getterów i seterów poza lenistwem. Skuteczna Java, która jest powszechnie uważana za jedną z najlepszych książek Javy, mówi, aby zawsze używać getterów i setterów. Jeśli nie musisz słyszeć o tym, dlaczego zawsze powinieneś używać getterów i setterów, pomiń ten akapit. Nie zgadzam się z przykładem odpowiedzi numer 1 punktu jako czasu, aby nie używać getterów i setterów. Jest z tym kilka problemów. Co zrobić, jeśli trzeba zmienić rodzaj numer. Na przykład, pewnego razu, kiedy eksperymentowałem z Grafiką, odkryłem, że często zmieniałem zdanie co do pogody, chcę przechowywać lokalizację w kształcie Javy lub bezpośrednio jako int, jak pokazał. Gdybym nie używał getterów i setterów i zmieniłem to, musiałbym zmienić cały kod, który używał lokalizacji. Jednak, jeśli nie mogę po prostu zmienić getter i setter.

Gettery i settery to ból w Javie. W Scali można tworzyć public data members i następnie getters I or setters później bez zmiany API. To daje najlepsze z obu światów! Być może Java kiedyś to naprawi.

 0
Author: jgleoj23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-24 04:01:07