Что такое инкапсуляция? Как это на самом деле скрывает данные? - PullRequest
6 голосов
/ 15 апреля 2011

Поиск приводит к простому определению: скрытие данных.

Но рассмотрим следующие два примера:

1) Первый пример:

Class Employee
{
    public int age;
}

2) Второй пример:

Class Employee
{
    private int age;

    public int getAge(){return age;}
}

Вопрос:
В обоих приведенных выше примерах скрытие данных отсутствует, так как age либо модифицируется другими, либо просматривается другими.Где скрываются данные?Как инкапсуляция помогает в приведенных выше примерах?

Ответы [ 7 ]

25 голосов
/ 15 апреля 2011

Там - это скрытие данных.Во втором примере скрывается, как хранится значение.Кроме того, второй пример делает значение доступным только для чтения для кода вне класса.Имея личные поля и открывая их с помощью методов или свойств, вы сразу получаете некоторые преимущества, некоторые из которых:

  • Детализация контроля доступа;Вы можете сделать значение общедоступным только для чтения, чтения и записи или только для записи.
  • Возможность проверки ввода перед сохранением значения
  • Возможность добавления ведения журнала или других механизмов аудита

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

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

3 голосов
/ 15 апреля 2011

Инкапсуляция отделяет понятие что-то делает от как это реализовано .

Инкапсуляция является очень важной концепцией в объектно-ориентированном программировании. Он скрывает данные от других модулей в приложении. В вашем примере 2, как вы можете видеть, вы можете получить только возраст и то же самое, используя метод getter, но вы можете установить значение только для закрытого члена в этом классе, а не вне его. Это преимущество инкапсуляции.

2 голосов
/ 15 апреля 2011

Подумайте об этом варианте:

class Employee
{
    private int _age;

    public string Age
    {
        get { return _age.ToString(); }
    }
}

В вашем примере снаружи и внутри используется целое число, и это сбивает с толку.(Аналогично показу 2 * 2 = 4 для объяснения умножения и забывания, что 2 + 2 = 4 тоже)

1 голос
/ 15 июня 2014

Encapsulation это просто data hiding.

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

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

Но предположим, что нам нужен человек, чтобы вводить данные о зарплате каждого из сотрудников.Я сделаю это более ясным.Пользователь, вводящий данные, имеет 3 типа данных для ввода woked_hours, OT and leaves (для этого в классе Emplyee есть три переменные).Мы хотим, чтобы этот человек ввел эти данные, но мы do not want его see, как это salary calculation сделано.Это делается в соответствии с математическим уравнением, которое находится внутри класса Employee.

Поэтому он не может самостоятельно рассчитывать и вводить зарплату.Но мы позволили ему увидеть окончательную зарплату.Мы создаем метод для получения значения зарплаты внутри класса сотрудников.это

public int getSalary()
{
   return salary;
} 

Он знает, что есть два метода, которые он может использовать для доступа к этим скрытым полям.set method and get method. Итак, он call getmethod. да, он can see информация salary.Потому что мы создали метод getMethod для возврата зарплаты.Теперь он пытается использовать заданный метод, чтобы ввести новую сумму заработной платы, чтобы изменить текущее значение заработной платы.поэтому он звонит e.setSalary(1000); но выдает ошибку.Зачем?потому что в классе работника нет метода, записанного как

   public void setSalary(int newSalary)
   {
   salary=newSalary;
   }

Мы специально не писали этот код, потому что не хотим, чтобы он сразу устанавливал значение зарплаты.Таким образом, мы скрыли некоторую информацию, но некоторые мы все еще позволяем ему доступМы дали ему доступ к Read only.Но not Write для зарплаты.

, так что теперь, когда мы сделали инкапсуляцию, было бесполезно.

Так же, как ему разрешено set эти поля woked_hours, OT and leaves.для этих полей мы дали ему доступ только для записи.Там мы намеренно не пишем getter methods.Если вы пишете и getter, и setter, вы разрешаете ему READ/ Write оба доступа.

Не имеет значения только установить или получить, поле является закрытым, поле скрыто, а данные скрыты.Но некоторый доступ предоставляется через getters и setters.

0 голосов
/ 15 апреля 2011

Скажи, что я использую твой код следующим образом:

Employee employee = new Employee();
int age = employee.getAge();
// Do something with age

Здесь, если я не посмотрю на ваш исходный код, я абсолютно не представляю, как Employee вычислил его возраст. Насколько я знаю, getAge() может выглядеть так:

public int getAge() {
    return new java.util.Random().nextInt( 100 );
}

или, возможно, что-то еще более сложное. Я просто не знаю.

Итак, во втором примере тот факт, что getAge() просто возвращает закрытую переменную-член, полностью скрыт от меня.

0 голосов
/ 15 апреля 2011

Инкапсуляция - это не просто сокрытие данных.Инкапсуляция позволяет хранить все данных и функциональных возможностей, относящихся к объекту с этим объектом.Уровни видимости этих данных являются связанной, но не идентичной концепцией.Например, объект Employee содержит все данные и функциональные возможности (методы) сотрудника.Обратите внимание, что это не принудительное , а включенное для языков ОО.

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

Цитата из Википедии article :

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

  • Языковой механизм для ограничения доступа к некоторым компонентам объекта,
  • Языковая конструкция, которая облегчает связывание данных с методами (или другими функциями), работающими с этими данными.
0 голосов
/ 15 апреля 2011

В вашем первом примере переменная age установлена ​​как публичная переменная.Здесь любой может изменить возраст, когда объявлен объект типа Employee.

Однако во втором примере переменная age на самом деле является закрытой и может быть изменена только внутри класса Employee.Это случай скрытия данных.

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

...