Jak działają gettery i setery?

107

Jestem ze świata PHP. Czy mógłbyś wyjaśnić, czym są metody pobierające i ustawiające, i podać kilka przykładów?

ajsie
źródło
@ yegor256 Rozumiem analogię z psem i piłką, a nawet ją popieram, ale co z „żywym organizmem”, który od czasu do czasu przechowuje pierwotną wartość, np. identyfikator? A co, jeśli chcesz wyjść poza proste przypisanie, ale nie chcesz pisać nowej klasy tylko do obsługi prymitywnych wartości?
Jacksonkr

Odpowiedzi:

127

Tutorial nie jest do tego naprawdę wymagany. Przeczytaj o hermetyzacji

private String myField; //"private" means access to this is restricted

public String getMyField()
{
     //include validation, logic, logging or whatever you like here
    return this.myField;
}
public void setMyField(String value)
{
     //include more logic
     this.myField = value;
}
Paul Creasey
źródło
11
więc getter jest po prostu metodą uzyskiwania pola prywatnego, a setter ustawia nowe pole. dzięki za doskonałe wyjaśnienie kodem
ajsie
1
czy możesz przekazać parametr do metody pobierającej?
ajsie
2
noname: Nie i nie. Getter jest sposobem na pobranie wartości, ale NIE ujawnia wartości zawartej w polu, to znaczy, jeśli wywołasz, someObj.getTime().setHour(5)nie powinno to wpływać na someObjstan wewnętrzny. Również metody ustawiające i pobierające (akcesory i mutatory według ich bardziej wyszukanej nazwy) mają bardzo ścisłą sygnaturę metody, co oznacza, że ​​getter nie ma żadnych parametrów. Generalnie metody i tak powinny robić tylko jedną rzecz.
Esko
4
@noname: Kiedy proste rzeczy otrzymują złożone / duże / abstrakcyjne nazwy, otrzymujesz coś, co nazywa się "wzorcem projektowym" ... A to jest przykład rekurencyjnego wzorca wyjaśniającego koncepcję, który właśnie wymyśliłem ;-)
namespaceform
3
@qed: thissłowo kluczowe jest opcjonalne, chyba że występuje konflikt z czymś, co ma bardziej szczegółowy zakres. W podanym przykładzie utworzony ustawiacz będzie miał jeden parametr, którego nazwa jest zgodna z nazwą pola, dlatego this.fieldName = fieldNamejest używany do rozróżnienia, do którego przypisywane jest pole, a nie parametr jest przypisywany do siebie, jak fieldName = fieldnameby się to stało. W getterze nie ma takiego konfliktu.
Paul Creasey
39

W Javie metody pobierające i ustawiające to zupełnie zwyczajne funkcje. Jedyną rzeczą, która czyni je getterami lub seterami, jest konwencja. Metoda pobierająca foo nazywa się getFoo, a metoda ustawiająca to setFoo. W przypadku wartości logicznej metoda pobierająca nazywa się isFoo. Muszą również mieć określoną deklarację, jak pokazano w tym przykładzie metody pobierającej i ustawiającej dla „nazwy”:

class Dummy
{
    private String name;

    public Dummy() {}

    public Dummy(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Powodem używania metod pobierających i ustawiających zamiast upubliczniania członków jest możliwość zmiany implementacji bez zmiany interfejsu. Ponadto wiele narzędzi i zestawów narzędzi wykorzystujących odbicie do badania obiektów akceptuje tylko obiekty, które mają metody pobierające i ustawiające. Na przykład komponenty JavaBeans muszą mieć metody pobierające i ustawiające, a także inne wymagania.

Mark Byers
źródło
9
Czy ci konstruktorzy nie powinni mieć „pustki”?
Jason Hartley,
Pustka jest tutaj faktycznie konieczna. Jeśli go nie masz, otrzymasz:error: invalid method declaration; return type required
Dan
3
Pustka nie jest tutaj wymagana
Shashi Kiran
2
@JasonHartley: Konstruktor nie ma typu zwracanego.
wassimans
@Mark Byers Zatem konstruktor jest używany do inicjalizacji instancji, a ustawiacz służy do zmiany dowolnego danego atrybutu. Czy to jest poprawne?
carloswm85
12
class Clock {  
        String time;  

        void setTime (String t) {  
           time = t;  
        }  

        String getTime() {  
           return time;  
        }  
}  


class ClockTestDrive {  
   public static void main (String [] args) {  
   Clock c = new Clock;  

   c.setTime("12345")  
   String tod = c.getTime();  
   System.out.println(time: " + tod);  
 }
}  

Po uruchomieniu programu program uruchamia się z sieci,

  1. obiekt c jest tworzony
  2. funkcja setTime()jest wywoływana przez obiekt c
  3. zmienna timejest ustawiana na wartość przekazaną
  4. funkcja getTime()jest wywoływana przez obiekt c
  5. czas jest zwracany
  6. To przejdzie todi todzostanie wydrukowane
user3137648
źródło
10

Możesz także przeczytać „ Dlaczego metody pobierające i ustawiające są złe ”:

Chociaż metody pobierające / ustawiające są powszechne w Javie, nie są one szczególnie zorientowane obiektowo (OO). W rzeczywistości mogą uszkodzić łatwość utrzymania kodu. Co więcej, obecność wielu metod pobierających i ustawiających jest sygnałem ostrzegawczym, że program niekoniecznie jest dobrze zaprojektowany z punktu widzenia obiektowego.

Ten artykuł wyjaśnia, dlaczego nie powinieneś używać metod pobierających i ustawiających (i kiedy możesz ich używać) oraz sugeruje metodologię projektowania, która pomoże Ci wyrwać się z mentalności pobierającej / ustawiającej.

superfav
źródło
3

1. Najlepsze metody pobierające / ustawiające są inteligentne.

Oto przykład javascript z Mozilli:

var o = { a:0 } // `o` is now a basic object

Object.defineProperty(o, "b", { 
    get: function () { 
        return this.a + 1; 
    } 
});

console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

Używałem ich DUŻO, ponieważ są niesamowite . Użyłbym tego, gdy polubiłem moje kodowanie + animację. Na przykład stwórz setera, który zajmuje się tym, Numberktóry wyświetla ten numer na twojej stronie internetowej. Kiedy setter jest używany, animuje starą liczbę do nowej liczby za pomocą tweenera . Jeśli początkowa liczba to 0 i ustawisz ją na 10, zobaczysz, że liczby szybko zmieniają się od 0 do 10 przez, powiedzmy, pół sekundy. Użytkownicy uwielbiają te rzeczy i fajnie jest tworzyć.

2. Programy pobierające / ustawiające w php

Przykład z sof

<?php
class MyClass {
  private $firstField;
  private $secondField;

  public function __get($property) {
    if (property_exists($this, $property)) {
      return $this->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this, $property)) {
      $this->$property = $value;
    }

    return $this;
  }
}
?>

cytaty:

Jacksonkr
źródło
2

Oto przykład wyjaśniający najprostszy sposób używania gettera i settera w java. Można to zrobić w prostszy sposób, ale metody getter i setter mają coś szczególnego, kiedy w dziedziczeniu używa się prywatnego członka klasy nadrzędnej w klasie potomnej. Możesz to umożliwić, używając getter i setter.

package stackoverflow;

    public class StackoverFlow 

    {

        private int x;

        public int getX()
        {
            return x;
        }

        public int setX(int x)
        {
          return  this.x = x;
        }
         public void showX()
         {
             System.out.println("value of x  "+x);
         }


        public static void main(String[] args) {

            StackoverFlow sto = new StackoverFlow();
            sto.setX(10);
            sto.getX();
            sto.showX();
        }

    }
Bashir ahmad
źródło
Nie zamierzam cię przegłosować (nie warte wysiłku). Należy pamiętać, że (1) odpowiedziałeś na pytanie dotyczące języka Java , gdzie język programu powinien być w języku Java. (2) Jeśli chcesz opublikować, upewnij się, że układ jest wykonany poprawnie. (3) Twoje użycie enkapsulacji (getter (lub akcesor) i setters (lub mutatorów)) jest nieprawidłowe. Proszę sprawdzić, co oznacza hermetyzacja ... (Sprawdź odpowiedź głosowaną)
KarelG
1
@KarelG przepraszam, nie przeczytałem tagów. zaktualizowałem go do java. dzięki za uświadomienie sobie mnie.
Bashir ahmad