Dlaczego metody getter i setter są ważne w Javie? [duplikat]

To pytanie ma już odpowiedź tutaj:

Nauczono mnie zawsze używać getterów i seterów. Nie znam jednak plusów i minusów tych metod, ponieważ wdrażając je ujawniamy dane, a także je ukrywamy.

Jestem trochę zdezorientowany. Can czy ktoś da jakąś właściwą radę dlaczego używamy gettera/settera i jakie są jego zalety?

Author: Nike15, 2012-01-12

6 answers

Podstawowy wzorzec "private field with public getter and setter that do nothing but return or set the field" jest całkowicie bezcelowy, jeśli chodzi o enkapsulację, z wyjątkiem tego, że daje Ci szansę na zmianę go później bez zmiany API.

Więc nie używaj tego wzoru bezmyślnie. Dokładnie zastanów się, jakich operacji naprawdę potrzebujesz.

Prawdziwym celem getterów i seterów jest to, że należy ich używać tylko tam, gdzie są odpowiednie i że mogą zrobić więcej niż tylko zdobywać i ustawiać pola.

  • możesz mieć tylko gettera. Wtedy właściwość jest tylko do odczytu. W rzeczywistości powinien to być najczęstszy przypadek.
  • możesz mieć tylko setter, dzięki czemu właściwość jest konfigurowalna, ale komunikując, że nic innego nie powinno zależeć od jej wartości
  • getter może obliczyć wartość z kilku pól zamiast zwracać jedno pole.
  • getter może wykonać kopię obronną
  • getter może leniwie wykonać kosztowną operację pobierania i użyć pole do buforowania wartości
  • seter może sprawdzać zdrowie psychiczne i rzucać IllegalArgumentException
  • setter może powiadamiać słuchaczy o zmianach wartości
  • możesz mieć setter, który ustawia wiele pól razem, ponieważ należą one do siebie koncepcyjnie. Nie jest to zgodne ze specyfikacją JavaBeans, więc nie rób tego, jeśli zależy ci na frameworkach lub narzędziach, które oczekują JavaBeans. W przeciwnym razie jest to przydatna opcja.

Wszystkie te rzeczy są szczegółami implementacji, które są ukryte za prostym interfejsem "getter and setter". Na tym polega enkapsulacja.

 56
Author: Michael Borgwardt,
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
2014-05-06 19:16:54

Idea getterów i setterów polega na kontrolowaniu dostępu do zmiennych w klasie. W ten sposób, jeśli wartość musi zostać zmieniona wewnętrznie, aby była reprezentowana w inny sposób, możesz to zrobić bez łamania żadnego kodu poza klasą.

Na przykład, załóżmy, że masz klasę ze zmienną odległości, i była mierzona w calach. Minęło kilka miesięcy, używasz tej klasy w wielu miejscach i nagle zdajesz sobie sprawę, że musisz reprezentować tę wartość w centymetrach. If you didn ' t użyj gettera i settera, będziesz musiał śledzić każde użycie klasy i konwertować tam. Jeśli użyłeś gettera i settera, możesz po prostu zmienić te metody i wszystko, co używa klasy, nie pęknie.

public class Measurement
{

    /**
     * The distance in centimeters.
     */
    private double distance;

    /**
     * Gets the distance in inches.
     * @return A distance value.
     */
    public double getDistance()
    {
        return distance / 2.54;
    }

    /**
     * Sets the distance.
     * @param distance The distance, in inches.
     */
    public void setDistance(double distance)
    {
        this.distance = distance * 2.54;
    }
}
 14
Author: Robert Rouhani,
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
2012-01-12 06:05:16

Dobrą zaletą jest to, że możesz utworzyć pole Tylko w trybie ReadOnly, nie implementując settera dla tego konkretnego pola.

 6
Author: Sandeep Pathak,
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
2012-01-12 06:02:47

Nie ma nic złego w używaniu getterów i seterów - po prostu pamiętaj, że używając ich i upubliczniając je, ujawniasz swoje zmienne i w pewien sposób naruszasz enkapsulację. To jest to, o czym artykuł, o którym wspomniałeś, stara się ostrzec - nie tylko automatycznie Generuj gettery i settery dla wszystkich prywatnych zmiennych instancji; pomyśl o tym, co chcesz ujawnić innym klasom (i na jakim poziomie, np. w razie potrzeby.

 2
Author: Amos M. Carpenter,
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
2012-01-12 06:10:24

Oto minusy. Getterzy / Setterzy mają tendencję do ujawniania szczegółów implementacji twojej klasy światu zewnętrznemu. To nie jest dobra rzecz. Wyobraź sobie, że piszesz pakiet oprogramowania dla mechaników samochodowych. W ten sposób będziesz potrzebował klasy samochodu, a więc wystawisz gettery i settery dla pól

Date lastOilChangeDate;
int lastOilChangeMileage;
W tej klasie. Dzieje się tak dlatego, że oprogramowanie chce wysyłać e-maile, gdy samochody klientów potrzebują wymiany oleju. [[2]} ale co się dzieje, gdy pojawiają się nowe samochody, gdzie można określić, czy samochód potrzebuje wymiany oleju inaczej niż "co 3000 mil lub 3 miesiące"? Być może te nowe samochody mają czujnik w misie olejowej, który mierzył Brud. Oczywiście chciałbyś użyć tego, aby określić, czy konieczna jest wymiana oleju. Problem polegał na tym, że rozwiązywałeś zły problem z tymi getter/seterami. Nikt tak naprawdę nie chce wiedzieć, kiedy była ostatnia wymiana oleju, chcą wiedzieć, czy potrzebujesz kolejnej. To były tylko szczegóły implementacji, ale zrobiłeś je częścią interfejsu. Co? you should have done was added a method
public boolean needsOilChange() 

I wtedy klasa samochodów mogła zaimplementować to, co chciała. Gdyby algorytm zmienił, Klasa Mechanika nie musiałaby tego robić, ponieważ wystarczyła tylko metoda needsOilChange.

 2
Author: MeBigFatGuy,
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
2012-01-12 06:29:21

Jest to najczęściej używane w Java beans, jak poniżej.

public Class MyBean{

private int var1;

public void setVar1(int pVar1){

this.var1=pvar1;

}

public int getVar1(){

Return var1` '

}

}

Korzyści są jak poniżej

1. Dzięki temu możemy osiągnąć enkapsulację

2. jest to wzorzec projektowy Dto (Data Transfer Object) . służy do przesyłania danych z jednej warstwy do drugiej warstwy w oparciu o MVC aplikacje. podobnie jak u można uzyskać dane wprowadzone przez użytkownika z formularza(za pomocą getterów) i u można użyć tych samych danych do wstawienia do bazy danych (za pomocą settera) i vice verca. najnowsze frameworki (SPring )dostarczające go jako wbudowaną funkcjonalność.

 -2
Author: Balaswamy Vaddeman,
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
2012-01-12 06:15:52