Подтвердить что ты не робот

Почему объявлять переменные частными в классе?

Люди, которые я начну с извинения, поскольку я уверен, что на это был дан ответ в другом месте - я просто не могу найти ответ, который объясняет это так, как я понимаю! Я делаю курс конверсии MSc, и есть некоторые элементарные основы, которые я все еще борется с этим, в том числе и этот - почему лучше сделать переменную private.

Скажем, у меня есть класс Java под названием Person, с методом печати. Я мог бы создать его и определить его как таковой:

public class Person
{
    public String name;
    public String telephoneNumber;

    public void print()
    {
       System.out.println(name + " " + telephoneNumber);
    }
}

Затем в основном классе я мог бы написать следующий код:

class testPerson
{
  public static void main(String[] args)
  {
    Person test;
    test = new Person();

    test.name = "Mary";
    test.telephoneNumber = "01234 567890";

    test.print();
  }
}

Если я сделал это, test.print(); будет производить вывод:

mary 01234 567890

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

Итак, теперь я отредактирую класс Person, чтобы объявить две строки приватными и добавить методы get и set, например:

private String name;
private String telephoneNumber;

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

public void getName()
{
  return name;
}

// same code for telephone methods.

Теперь, в основном классе, я бы изменил методы установки имени и телефона на следующее:

mary.setName("Mary");
mary.settelephoneNumber("01234 567890");

В соответствии с примечаниями к лекции, которые я придерживаюсь, это более эффективно (хотя может быть сделано еще более эффективно, добавив в метод Person() для создания экземпляра и т.д.)

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

Почему это предпочтено и что, без сомнения, глупость я не вижу/не замечаю?

4b9b3361

Ответ 1

Это не то, что он более эффективен, а потому что он более удобен в обслуживании и имеет хорошую практику.

Например, с помощью методов setter вы можете проверить, что setTelephoneNumber действительно правильный номер телефона String, прежде чем вы действительно выполните настройку. Вы не могли бы этого сделать, если бы вы сделали переменную открытой. Использование сеттера с самого начала означает, что вы можете вернуться назад и, например, добавьте проверку позже, тогда как если бы вы сделали переменную общедоступной, вам нужно было бы добавить сеттер и изменить всех своих пользователей во всем мире, чтобы использовать установщик вместо изменения переменной напрямую.

Ответ 2

Аналогия доставки пиццы

  • Вы заказываете пиццу для доставки.
  • Мальчик-пицца выбивает дверь и ожидает, что вы заплатите за нее.
  • Вы берете деньги из своего кошелька и передаете его мальчику. (Вы контролируете скрытие внутренних деталей (водительские права и т.д.)) В качестве альтернативы
    • Вы можете передать кошелек мальчику доставки и попросить его взять у него деньги. Поступая таким образом, вы больше не контролируете. Вы раскрываете внутренние детали.

Читайте о Сокрытие информации и Инкапсуляция не скрывает информацию.

Ответ 3

Люди дадут вам миллион извращенных причин, почему это лучше, но это лучше только в некоторых случаях, а не во всех из них однозначно. Например, возьмите собственный класс Java GridBagConstraints у него вообще нет методов (если вы этого не сделаете count clone, который он имеет в любом случае, все классы Java наследуют его от Object). Зачем? Потому что есть случай, когда это на самом деле более практично. И GridBagConstraints - это Java Bean в чистом смысле: все о свойствах, там нет бизнес-логики.

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

Современные Java-API, такие как Hibernate, подтверждают этот факт, принимая голые общедоступные поля наравне с свойствами стиля JavaBean. Более ранние версии этого не допускали, но по мере накопления опыта Java, реализация, наконец, приходит к выводу, что открытые поля ОК.

Ответ 4

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

Хорошим литералом будет размер растрового объекта. Большинству машин это не понравилось бы, если бы вы попытались нарисовать растровое изображение размеров -10x-10, потому что такое было бы невозможно представить на экране. Если свойства width/height этого растрового изображения были просто общедоступными переменными, возможно, в будущем они могут быть установлены неверными значениями с помощью хорошо продуманного кодера (НИКОГДА не предполагайте, что этого не произойдет), и когда это произойдет, чтобы сделать это - bang, у вас есть замороженный компьютер.

Скрывая переменные и используя сеттер, вы можете предотвратить это:

private int _width = 10;

public void setWidth(int value)
{
     //Prevent the value moving into invalid range:

     if(value < 1)
          value = 1;

     if(value > 4096)
          value = 4096;

     //Now apply it
     _width = value;
}

Тем не менее, для скорости и удобства вам не нужно сначала разрабатывать свой код, как это, просто убедитесь, что вы прошли через него и спрятали то, что вам нужно!

Ответ 5

есть также проблемы с безопасностью. общим примером является банковский счет. у вас есть баланс, и вы используете депозит для ввода денег, а также вывод средств для снятия денег. если баланс был открытым, его можно было бы изменить без внесения или снятия денег. это может быть ОЧЕНЬ плохо.

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