Зачем объявлять переменные private в классе? [закрытый]

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

скажем, у меня есть класс 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();
  }
}

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

mary 01234 567890

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

Итак, теперь я отредактирую класс Person, чтобы объявить две строки private и добавить методы 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 (), чтобы разрешить создание экземпляра и т. д.)

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

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

5 ответов


дело не в том, что это более эффективно, а в том, что это более ремонтопригодно и хорошая практика.

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


Аналогия Доставки Пиццы

  1. вы заказываете пиццу для доставки.
  2. Pizza boy стучит в дверь и ожидает, что вы заплатите за это.
  3. вы берете деньги из кошелька и передаете их посыльному. (Вы контролируете скрытие внутренних данных (водительские права и т. д.)) кроме того,
    • вы можете передайте кошелек посыльному и попросите его взять с него деньги. делая это вы больше не контролируете. Вы раскрываете внутренние детали.

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


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

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

современные API Java, такие как Hibernate, признают этот факт принимая голым полям наравне с JavaBean в стиле свойства. Более ранние версии не позволяли этого, но по мере накопления опыта работы с Java, наконец, осознается, что public fields ОК.


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

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

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

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;
}
, для скорости и удобства вам не нужно сначала разрабатывать свой код-просто убедитесь, что вы пройдете через него позже и спрячете то, что вам нужно!

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

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