Как работают геттеры и сеттеры?

108

Я из мира php. Не могли бы вы объяснить, что такое геттеры и сеттеры, и привести несколько примеров?

Эйси
источник
@ yegor256 Я понимаю вашу аналогию с собакой и мячом и даже поддерживаю ее, но как насчет случая, когда объект "живой организм" хранит случайные примитивные значения, например идентификатор? Что, если вы хотите выйти за рамки простого присваивания, но не хотите писать новый класс только для обработки примитивных значений?
Jacksonkr

Ответы:

127

Учебник для этого не требуется. Прочтите об инкапсуляции

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;
}
Пол Кризи
источник
11
так что геттер - это просто метод получения частного поля, а сеттер устанавливает новое поле. спасибо за отличное объяснение по коду
ajsie
1
не могли бы вы передать параметр получателю?
ajsie
2
noname: Нет и нет. Getter - это способ получить значение, но НЕ раскрывать значение, содержащееся в поле, то есть если вы someObj.getTime().setHour(5)его вызываете, это не должно влиять someObjна внутреннее состояние. Также сеттеры и геттеры (аксессоры и мутаторы по их более интересному имени) имеют очень строгую сигнатуру метода, что означает, что у геттера нет никаких параметров. В любом случае методы в целом должны делать только одно.
Esko
4
@noname: Когда простым вещам присваиваются сложные / большие / абстрактные имена, у вас есть то, что называется «шаблоном проектирования» ... И это пример шаблона объяснения рекурсивных концепций, который я только что придумал ;-)
namespaceform
3
@qed: thisключевое слово необязательно, если нет конфликта с чем-то, имеющим более конкретную область действия. В приведенном вами примере созданный установщик будет иметь один параметр, имя которого совпадает с именем поля, следовательно this.fieldName = fieldName, он используется, чтобы отличить, что поле назначается, а не параметр, назначаемый самому себе, как это fieldName = fieldnameбыло бы возможно. В геттере такого конфликта нет.
Пол Кризи,
39

В Java геттеры и сеттеры - это совершенно обычные функции. Единственное, что делает их геттерами или сеттерами, - это условность. Метод получения для foo называется getFoo, а метод установки - setFoo. В случае логического значения метод получения называется isFoo. У них также должно быть определенное объявление, как показано в этом примере получателя и сеттера для 'name':

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;
    }
}

Причина использования геттеров и сеттеров вместо того, чтобы делать ваших членов общедоступными, заключается в том, что это позволяет изменять реализацию без изменения интерфейса. Кроме того, многие инструменты и наборы инструментов, которые используют отражение для исследования объектов, принимают только те объекты, у которых есть геттеры и сеттеры. JavaBeans, например, должны иметь геттеры и сеттеры, а также некоторые другие требования.

Марк Байерс
источник
9
Разве у этих конструкторов не должно быть void?
Джейсон Хартли
Здесь действительно нужна пустота. Если у вас его нет, вы получите:error: invalid method declaration; return type required
Дэн
3
Пустота здесь не обязательна
Шаши Киран
2
@JasonHartley: конструктор не имеет возвращаемого типа.
вассиманы 03
@Mark Byers Итак, конструктор используется для инициализации экземпляра, а установщик используется для изменения любого заданного атрибута. Это верно?
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);  
 }
}  

При запуске программы программа запускается в сети,

  1. объект c создан
  2. функция setTime()вызывается объектом c
  3. переменной timeустанавливается значение, переданное
  4. функция getTime()вызывается объектом c
  5. время возвращается
  6. Он перейдет todи todбудет распечатан
user3137648
источник
10

Вы также можете прочитать « Почему методы получения и установки - это зло »:

Хотя методы получения и установки являются обычным явлением в Java, они не особо объектно-ориентированы (OO). Фактически, они могут повредить ремонтопригодность вашего кода. Более того, наличие множества методов получения и установки - это красный флаг, что программа не обязательно хорошо спроектирована с точки зрения объектно-ориентированного программирования.

В этой статье объясняется, почему вам не следует использовать геттеры и сеттеры (и когда их можно использовать), и предлагается методология проектирования, которая поможет вам выйти из менталитета геттеров / сеттеров.

superfav
источник
3

1. Лучшие геттеры / сеттеры умны.

Вот пример javascript от Mozilla:

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)

Я использовал их МНОГО, потому что они классные . Я бы использовал его, когда начинал работать с кодированием + анимацией. Например, создайте сеттер, Numberкоторый будет отображать этот номер на вашей веб-странице. Когда используется сеттер, он анимирует старое число в новое число с помощью твинера . Если исходное число равно 0, и вы установите его на 10, вы увидите, как числа быстро меняются от 0 до 10, скажем, за полсекунды. Пользователи любят эти вещи, и их интересно создавать.

2. Геттеры / сеттеры в php

Пример от соф

<?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;
  }
}
?>

цитаты:

Джексонкр
источник
2

Вот пример, объясняющий самый простой способ использования методов получения и установки в java. Можно сделать это более простым способом, но у геттера и сеттера есть что-то особенное, что происходит при использовании закрытого члена родительского класса в дочернем классе в наследовании. Вы можете сделать это возможным, используя геттер и сеттер.

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();
        }

    }
Башир Ахмад
источник
Я не собираюсь опускать вас (не стоит усилий). Имейте в виду, что (1) вы ответили на вопрос о Java , где должен быть язык программы на Java. (2) Если вы хотите опубликовать, убедитесь, что макет сделан правильно. (3) Вы неправильно используете инкапсуляцию (геттер (или аксессор) и сеттеры (или мутаторы)). Пожалуйста, посмотрите, что означает инкапсуляция ... (Проверьте проголосованный ответ)
KarelG
1
@KarelG извините, я не прочитал теги. я обновил его до java. спасибо, что поняли меня.
Башир