Java-OOP 04 - Инкапсуляция - encapsulation

Инкапсуляция - encapsulation #

В слове инкапсуляция корень капсула. Если мы спрячем в “капсулу” параметры объекта, то это и будет инкапсуляцией.

Инкапсуляция - encapsulation

Инкапсуляция - encapsulation

Зачем нужна инкапсуляция? #

Во-первых, к некоторым параметрам не должно быть доступа ни у других программ, ни у пользователей, ни у (даже!) программистов. Например:

  1. Поле день рождения в программе паспортного стола. Посмотреть его можно. Изменить нельзя. Это поле должно быть создано в месте с записью о человеке и позже его менять нельзя.
  2. Второй пример банковские счета. Никто не должен иметь возможность изменить состояние счёта просто вписав в поле 1_000_000€.
  3. Хороший пример с комментарием пользователя на форуме. Его можно создать, изменить, удалить. Но может это сделать не любой, а только сам пользователь или например админ, модератор сайта.
  4. Хороший пример пожалуй реализован в некоторых играх дополненной реальности. В зависимости от того, где находится пользователь, появляется доступ к различным параметрам игры - игровым боссам, кладам и так далее. То есть координаты нашего расположения берутся напрямую из телефона. И ни у кого нет возможности повлиять на эти данные.

Надеюсь вопрос зачем - решён.

Как в Java реализована инкапсуляция? #

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

Модификаторы доступа в Java #

_ Class Package Subclass(same pkg) Subclass(diff pkg) World
public + + + + +
protected + + + +
no modifier + + +
private +

Самый закрытый доступ у модификатора private. Он разрешает доступ только методам этого же класса. Самая высокая ступень видимости у public. Любой метод может получить доступ к полю. Разницу между protected и отсутствием модификатора можно увидеть при работе с наследованием.

public class Cat {
    private String name;
    private int age;
    private String breed;
    private boolean pass;

    public Cat(String name, int age, String breed) {
        this.name = name;
        this.age = age;
        this.breed = breed;
    }

    void move() {
        System.out.println("Я двигаюсь!!!");
    }
}

Какие части программы надо инкапсулировать(скрывать)? #

Принципиально вопрос надо ставить по другому. Какие не надо? Все параметры класса должны быть защищены. И только для тех параметров, которых необходимо можно изменить модификатор.

То есть, если нет необходимости всегда private.

Как посмотреть данные скрытого поля или даже изменить? #

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

public void setPass(boolean pass) {
    this.pass = pass;
}

Мы передаём новое значение и изменяем его. В название поля всегда есть слово set и потому их так и прозвали.

Метод, который показывает нам значение поля, называется гетер. Потому что в название метода всегда есть get.

    public boolean isPass() {
        return pass;
    }

Ну почти всегда. Всегда если это не boolean. Запомните это, пожалуйста. Гетеры для остальных полей класса Cat:

public String getName() {
    return name;
}

public int getAge() {
    return age;
}

public String getBreed() {
    return breed;
} 

Как мы видим конвенция для названия метода достаточно проста. Используй get, is или set и само название поли и соедини их через CamelCase нотацию.

Сам класс теперь выглядит вот так.

public class Cat {
    private String name;
    private int age;
    private String breed;
    private boolean pass;

    public Cat(String name, int age, String breed) {
        this.name = name;
        this.age = age;
        this.breed = breed;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getBreed() {
        return breed;
    }

    public boolean isPass() {
        return pass;
    }

    public void setPass(boolean pass) {
        this.pass = pass;
    }

    void move() {
        System.out.println("Я двигаюсь!!!");
    }
}

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

Очень часто (и такое будет в домашнем задании) лепят гетеры ко всем полям класса. Разумно делать только те гетеры и тем более сетеры, которые действительно нужны.

Домашнее задание #

  1. Создайте если ещё не создали класс книги.
  2. Добавьте параметры в свои книги. Всего должно быть около 10.
  3. Создайте метод закладки для книги.
  4. Сделайте ко всем полям гетеры и сетеры(практики ради).
  5. Создайте 10 объектов книги.
  6. Создайте массив из этих 10 объектов.
  7. Отсортируйте массив поочерёдно по автору, по году издания, по количеству страниц.
comments powered by Disqus