2012-01-24 17 views
8

W klasach zmienne często stają się prywatne dla enkapsulacji, a ograniczenie zmiennych do pewnego zakresu umożliwia lepszą kontrolę błędów i mniej błędów. Ma to sens, ponieważ im mniej miejsc dostępnych jest zmienna, tym mniej miejsc może wystąpić błąd związany z tą zmienną.Jaki jest punkt dostępu do prywatnych zmiennych poprzez funkcje getter i setter (accessor)?

Jednak zawsze widzę zmienne miały charakter prywatny, a następnie funkcję getter i setter używany do pobierania tej wartości (czasami nawet wskaźnik do tej zmiennej!). Na przykład int a jest prywatny, aby uniemożliwić publiczny dostęp, ale wtedy getA() i setA() umożliwiają bezpośredni dostęp do nich.

Więc nie zbieraj funkcji i funkcji ustawiacza, które nie pozwalają na zachowanie prywatności? Chodzi mi o to, że zmienne prywatne z funkcjami dostępowymi są takie same jak zmienne publiczne, a tylko kod umożliwiający dostęp do nich. (object.variable vs object.getVariable())

Czy istnieje powód, dla którego ludzie wprowadzają zmienne jako prywatne z funkcjami akcesor? Czy są jakieś zalety w porównaniu z upublicznieniem?

mówię o programowaniu w ogóle, ale przede wszystkim w językach C (czyli C, C++, C#, Obj-C).

+1

To naprawdę zależy od języka. W restrykcyjnie językach OO (C#, Java), gettery/settery są popularnym idiomem, podczas gdy w swobodniejszym języku, takim jak C++, są one zwykle złym stylem. –

Odpowiedz

11

Kluczowym słowem i znacznikiem jest tutaj "enkapsulacja". Ukrywasz szczegóły a, wciąż czyniąc je użytecznymi. Podobają mi się powody już wymienione, jest ich o wiele więcej. Tutaj jest inny, debugujesz, a znajdziesz a ma nieprawidłową wartość. Jeśli a jest publiczne, musisz sprawdzić każde miejsce, do którego można uzyskać dostęp z domeny a. Jeśli a jest prywatna z metody setter wiesz jedynym miejscem a mógł zmienić to w wywołaniu setA() - byłoby to świetne miejsce, aby umieścić punkt przerwania;)

+0

+1 do debugowania –

+0

Zrozumiałem to doskonale, dzięki :) – fdh

+0

W zależności od procesora (takiego jak X86), debugger może ustawić punkt przerwania danych (lub tracepoint) na dowolnym zapisie do zmiennej, która dokonałaby tego samego. – rcgldr

2

Bo jeśli zmienisz wewnętrzną reprezentację tej zmiennej lub chcesz zrobić więcej, gdy jest ona ustawiona lub pobrana, nie będzie ona łamać wszystkich innych klas, które z niej korzystają (a jeśli jest to biblioteka, nie musisz zmień swój interfejs API).

Oznacza to również można łatwo ustawić punkt przerwania, aby zobaczyć, kiedy przyzwyczaja (choć większość języki/debugger posiada danych breakpoints pewnego rodzaju).

2

Być może będziesz chciał dodać kilka kontroli do następnej wersji biblioteki (lub zrobić coś, gdy ktoś odczyta wartość), a jeśli zmienna będzie publiczna w bieżącej wersji, uaktualnienie wersji biblioteki będzie kosztować dużo pracy.

0

Klasa definiuje zachowanie, a członkami są państwa obiektu ... więc mając setter i getter definiuje zachowanie enkapsulacji klasy pozwalającej innym znaleźć/zmienić stan obiektów.

Innymi słowy, różnica polega na tym, że pozwalasz swojemu sąsiadowi wejść do twojego domu i wziąć to, co on chce (uczynić cały obiekt publicznie w klasie) ... lub upewniając się, że sąsiad przychodzi, pyta mnie, co chce i daję mu (mającego kupującego/ustawiającego)

0

Dlaczego wymagane jest hermetyzacja? Dlaczego wymagane jest OOP? Czy język programowania C nie był w stanie zrobić tego, co robimy dzisiaj? Zapytaj o to swojego. Lub jeśli pracowaliście nad dużymi systemami mającymi miliony linii kodu. A wszystko, czego używałeś, to zmienne publiczne o kluczowej strukturze danych dostępne z każdego modułu programu.

+0

pytanie w odpowiedzi? – manetsus

0

Miałem to samo na myśli, gdy zacząłem się uczyć programowania obiektowego, ponieważ w większości książek po prostu zmieniono je na prywatne i dodałem publiczne metody (Getter/Setters), aby uzyskać do nich dostęp, więc pomyślałem, czy mogę uzyskać dostęp do tę zmienną za pomocą metod, które są publiczne, co jest wskazane, aby ta zmienna była prywatna.

Otrzymuję odpowiedź Po rozpoczęciu wdrażania rzeczywistej aplikacji biznesowej.

Rozważmy ucznia klasy, które zawierają nazwę Student, roll nie, znaki z 3 przedmiotów

Class Student { 

    private int rollno; 
    private int java_marks; 
    private int cpp_marks; 
    private int unix_marks; 
    private int percentage; 


    public int getJava_marks() { 
     return java_marks; 
    } 
    public void setJava_marks(int java_marks) { 
     if (java_marks > 100) { 
      System.out.println("Marks value should be less than 100"); 
      //throw exception 
     } 
     this.java_marks = java_marks; 
    } 
    public int getCpp_marks() { 
     return cpp_marks; 
    } 
    public void setCpp_marks(int cpp_marks) { 
     if (cpp_marks > 100) { 
      System.out.println("Marks value should be less than 100"); 
      //throw exception 
     } 
     this.cpp_marks = cpp_marks; 
    } 
    public int getUnix_marks() { 

     return unix_marks; 
    } 
    public void setUnix_marks(int unix_marks) { 
     if (unix_marks > 100) { 
      System.out.println("Marks value should be less than 100"); 
      //throw exception 
     } 
     this.unix_marks = unix_marks; 
    } 
    public int getPercentage() { 
     this.percentage = (this.cpp_marks + this.unix_marks + this.java_marks) /3; 
     return percentage; 
    } 

    public int getRollno() { 
     return rollno; 
    } 
    public void setRollno(int rollno) { 
     this.rollno = rollno; 
    } 

} 

Tutaj uczynić zmiennych prywatnych ze względu na 2 powodów

  1. Walidacja: jeśli użytkownik dostarcza niepoprawna wartość znaczników, wówczas obiekt ucznia nie powinien tworzyć z niepoprawnymi danymi i zgłaszać odpowiedniego błędu/wyjątku. W przypadku znaczników jako zbiorowisk publicznych użytkownik może ustawić dowolną wartość dla nich, więc dodałem sprawdzanie poprawności/zabezpieczenia, aby zapewnić, że poszczególne obiekty ucznia otrzymały poprawne dane.

  2. Zabezpieczenia W przypadku wartości procentowej użytkownik nie może ustawić własnej wartości procentowej. procent jest obliczany i ustalany wewnętrznie. Tutaj nie udostępniam metody ustawiania procentu, aby użytkownik mógł uzyskać/odczytać wartość procentową tylko za pomocą metody getter.

To prowadzi do bezpieczeństwa w abstrakcji, która jest tylko ograniczona (tylko do odczytu) dostęp do zmiennej klasy.

Powiązane problemy