
Инкапсуляция не предназначена для сокрытия данных
При определении инкапсуляции многие будут ссылаться на то, что инкапсуляция
- Обертывание данных и функциональности и представление их как единого объекта
- Скрытие элементов данных для обеспечения безопасности
Ну хотя для инкапсуляции нет. 1 верно нет. 2 не всегда верно.
Давайте разберемся, почему.
Сотрудник.java
public class Employee{
private String name;
private int age;
private String designation;
private EmployeeAddress employeeAddress = new EmployeeAddress();
public Employee(String name, int age, String designationn){
this.name = name;
this.age = age;
this.designation = designationn;
}
....
....
// getter and setters
....
....
}
EmployeeAddress.java
public class EmployeeAddress{
private String city;
private String area;
private int postalCode;
...
...
// getter and setters
...
...
}
Test.java
public class Test{
public static void main(String[] args) {
Employee employee = new Employee("Ross", 30, "Paleontologist");
EmployeeAddress employeeAddress = employee.getEmployeeAddress();
employeeAddress.setCity("Dhaka");
employeeAddress.setArea("Dhanmondi");
employeeAddress.setPostalCode(1209);
System.out.println(employee.toString());
}
}
Вывод:
Employee [age=30, designation=Paleontologist, name=Ross, employeeAddress=EmployeeAddress [area=Dhanmondi, city=Dhaka, postalCode=1209]]
Как мы видим, мы можем манипулировать EmployeeAddress без вызова метода установки для объекта EmployeeAddress. Хотя класс Employee инкапсулирован, мы все же можем изменить объект EmployeeAddress без вызова для него метода установки. Таким образом, EmployeeAddress здесь не скрывается.
Так зачем же тогда инкапсуляция?
- Это обеспечивает лучшее повторное использование, гибкость и удобство обслуживания.
Если мы изменим поле поля класса Employee, другие классы не будут иметь побочного эффекта. Поскольку они получают доступ к полю через методы получения и установки. - Это дает абстракцию
Допустим, мы хотим проверить возраст поля. Итак, нам нужно реализовать логику проверки внутри метода setAge(). Пользователю не нужно знать логику проверки. Он просто передаст значение.
public void setAge(int age){
if (age > 30){
throw new IllegalArgumentException("Age can't be greater than 30");
}
this.age = age;
}
3. Мы можем добиться режима только для чтения/записи
Мы можем сделать поле доступным только для чтения, предоставив ему только метод getter(). Или мы можем сделать его доступным только для записи, предоставив ему только метод setter().