Як працюють геттери та сетери?


107

Я з світу php. Чи можете ви пояснити, що таке геттери та сетери та чи можете ви навести кілька прикладів?


@ yegor256 Я розумію вашу аналогію з собакою та м'ячем, і я навіть її підтримую, але як бути, коли об’єкт "живого організму" зберігає первісне значення, наприклад, ідентифікатор? Що робити, якщо ви хочете вийти за рамки простого завдання, але не хочете писати новий клас лише для обробки примітивних значень?
Джексонкр

Відповіді:


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
тому getter - це лише метод отримання приватного поля, а сетер - це встановлення нового поля. дякую за чудове пояснення за кодом
ajsie

1
Ви можете передати параметр геттеру?
ajsie

2
noname: Ні і ні. Getter - це спосіб отримати значення, але НЕ виставляти значення, що міститься в полі, тобто, якщо ви someObj.getTime().setHour(5)його називаєте, це не повинно впливати someObjна внутрішній стан. Також сетери та геттери (аксесуари та мутатори за своїм фанатичним іменем) мають дуже суворий метод підпису, тобто геть не має жодних параметрів. Взагалі методи повинні робити лише одне.
Есько

4
@noname: Коли простим речам присвоюються складні / великі / абстрактні імена, у вас є те, що називається "шаблон дизайну" .... І це приклад пояснювальної схеми рекурсивної концепції, яку я щойно винайшов ;-)
форма імен

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
Чи не повинні у цих конструкторів бути "недійсними"?
Джейсон Хартлі

Порожня тут фактично необхідна. Якщо у вас її немає, ви отримуєте:error: invalid method declaration; return type required
День

3
Порожнеча тут не потрібна
Шаші Кіран

2
@JasonHartley: Конструктор не має типу повернення.
wassimans

@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роздрукується

10

Ви також можете прочитати " Чому методи геттера та сетера є злими ":

Хоча методи геттера / сеттера є звичайними для Java, вони не є особливо об'єктно-орієнтованими (OO). Насправді вони можуть зашкодити ремонтопридатності вашого коду. Більше того, наявність численних методів геттера та сеттера є червоним прапором, що програма не обов'язково розроблена з точки зору ОО.

Ця стаття пояснює, чому ви не повинні використовувати геттери та сетери (і коли ви можете їх використовувати), і пропонує методику розробки, яка допоможе вам вийти з ментальності геттера / сетера.


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. дякую, що мене зрозуміли.
Башир ахмад
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.