Java Language
Getters and Setters
Szukaj…
Wprowadzenie
Dodawanie Getters i Setters
Enkapsulacja jest podstawową koncepcją w OOP. Chodzi o zawijanie danych i kodu jako pojedynczej jednostki. W takim przypadku dobrą praktyką jest zadeklarowanie zmiennych jako private
a następnie dostęp do nich za pośrednictwem Getters
i Setters
aby je wyświetlić i / lub zmodyfikować.
public class Sample {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Te prywatne zmienne nie są dostępne bezpośrednio spoza klasy. Dlatego są chronione przed nieautoryzowanym dostępem. Ale jeśli chcesz je wyświetlić lub zmodyfikować, możesz użyć Getters and Setters.
getXxx()
zwróci bieżącą wartość zmiennej xxx
, podczas gdy można ustawić wartość zmiennej xxx
za pomocą setXxx()
.
Konwencje nazewnictwa metod są (w przykładzie zmienna nazywa się variableName
):
Wszystkie zmienne niebędące wartościami
boolean
getVariableName() //Getter, The variable name should start with uppercase setVariableName(..) //Setter, The variable name should start with uppercase
zmienne
boolean
isVariableName() //Getter, The variable name should start with uppercase setVariableName(...) //Setter, The variable name should start with uppercase
Obiekty pobierające i ustawiające publiczne są częścią definicji właściwości komponentu Java Bean.
Korzystanie z setera lub gettera w celu zaimplementowania ograniczenia
Setters i Getters pozwalają, aby obiekt zawierał prywatne zmienne, do których można uzyskać dostęp i zmieniać je z ograniczeniami. Na przykład,
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
if(name!=null && name.length()>2)
this.name = name;
}
}
W tej klasie Person
istnieje jedna zmienna: name
. Dostęp do tej zmiennej można uzyskać za pomocą metody getName()
i zmienić za pomocą metody setName(String)
, jednak ustawienie nazwy wymaga, aby nowa nazwa miała długość większą niż 2 znaki i nie była zerowa. Użycie metody ustawiającej zamiast upublicznienia name
zmiennej pozwala innym ustawić wartość name
z pewnymi ograniczeniami. To samo można zastosować do metody gettera:
public String getName(){
if(name.length()>16)
return "Name is too large!";
else
return name;
}
W powyższej zmodyfikowanej metodzie getName()
name
jest zwracana tylko wtedy, gdy jej długość jest mniejsza lub równa 16. W przeciwnym razie zwracane jest "Name is too large"
. Pozwala to programiście tworzyć zmienne, które są osiągalne i modyfikowalne w dowolny sposób, zapobiegając niechcianej edycji zmiennych przez klasy klientów.
Dlaczego warto korzystać z Getters i Setters?
Rozważ podstawową klasę zawierającą obiekt z modułami pobierającymi i ustawiającymi w Javie:
public class CountHolder {
private int count = 0;
public int getCount() { return count; }
public void setCount(int c) { count = c; }
}
Nie możemy uzyskać dostępu do zmiennej count
, ponieważ jest ona prywatna. Ale możemy uzyskać dostęp do metod setCount(int)
getCount()
i setCount(int)
, ponieważ są one publiczne. Dla niektórych może to rodzić pytanie; po co wprowadzać pośrednika? Dlaczego po prostu nie upublicznić ich?
public class CountHolder {
public int count = 0;
}
Wszystkie te cele są dokładnie takie same pod względem funkcjonalności. Różnica między nimi polega na rozszerzalności. Zastanów się, co mówią poszczególne klasy:
- Po pierwsze : „Mam metodę, która da ci wartość
int
, i metodę, która ustawi tę wartość na innąint
”. - Po drugie : „Mam
int
, który możesz ustawić i otrzymać według własnegoint
”.
Może to zabrzmieć podobnie, ale pierwsza z nich jest o wiele bardziej strzeżona ze swej natury; to tylko pozwala na interakcję z jego wewnętrznej natury, co dyktuje. To pozostawia piłkę na boisku; wybiera sposób interakcji wewnętrznych. Drugi ujawnił swoją wewnętrzną implementację zewnętrznie i jest teraz nie tylko podatny na zewnętrznych użytkowników, ale, w przypadku interfejsu API, zobowiązuje się do utrzymania tej implementacji (lub w inny sposób wydania niekompatybilnego wstecz API).
Zastanówmy się, czy chcemy zsynchronizować dostęp do modyfikacji i dostępu do liczby. W pierwszym jest to proste:
public class CountHolder {
private int count = 0;
public synchronized int getCount() { return count; }
public synchronized void setCount(int c) { count = c; }
}
ale w drugim przykładzie jest to teraz prawie niemożliwe bez przejścia i modyfikacji każdego miejsca, do którego odwołuje się zmienna count
. Co gorsza, jeśli jest to element, który udostępniasz w bibliotece, aby mógł być używany przez innych, nie masz możliwości wykonania tej modyfikacji i musisz dokonać trudnego wyboru, o którym mowa powyżej.
To nasuwa pytanie; czy zmienne publiczne są kiedykolwiek dobre (a przynajmniej nie złe)?
Nie jestem pewien Z jednej strony można zobaczyć przykłady zmiennych publicznych, które przetrwały próbę czasu (IE: zmienna out
, do której odwołuje się System.out
). Z drugiej strony, podanie zmiennej publicznej nie daje żadnych korzyści poza wyjątkowo minimalnym kosztem ogólnym i potencjalnym zmniejszeniem słownictwa. Moją wskazówką byłoby, aby jeśli planujesz upublicznić zmienną, powinieneś ją ocenić na podstawie tych kryteriów z wyjątkowymi uprzedzeniami:
- Zmienna nie powinna mieć żadnego możliwego powodu, aby kiedykolwiek zmienić jej implementację. Jest to coś, co jest niezwykle łatwe do zepsucia (i nawet jeśli zrobisz to dobrze, wymagania mogą się zmienić), dlatego też metody pobierające / ustawiające są powszechnym podejściem. Jeśli masz mieć zmienną publiczną, naprawdę trzeba to przemyśleć, szczególnie jeśli jest ona dostępna w bibliotece / frameworku / API.
- Zmienna musi być przywoływana wystarczająco często, aby uzasadniały ją minimalne korzyści wynikające ze zmniejszenia szczegółowości. Nawet nie sądzę, że należy wziąć pod uwagę narzut związany z używaniem metody w porównaniu do bezpośredniego odwoływania. Jest to zdecydowanie zbyt mało znaczące, dla tego, co konserwatywnie oceniam na 99,9% wniosków.
Prawdopodobnie jest coś więcej, niż się spodziewałem. W razie wątpliwości zawsze używaj getterów / seterów.