«1. Обзор

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

2. Ключевое слово

Модификатор доступа private важен, потому что он позволяет инкапсулировать и скрывать информацию, которые являются основными принципами объектно-ориентированного программирования. Инкапсуляция отвечает за связывание методов и данных, а сокрытие информации является следствием инкапсуляции — она скрывает внутреннее представление объекта.

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

3. Поля

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

Во-первых, давайте создадим класс Employee, содержащий пару частных переменных экземпляра:

public class Employee {
    private String privateId;
    private boolean manager;
    //...
}

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

4. Конструкторы

Теперь создадим приватный конструктор:

private Employee(String id, String name, boolean managerAttribute) {
    this.name = name;
    this.privateId = id + "_ID-MANAGER";
}

Пометив наш конструктор как приватный, мы сможем использовать его только внутри нашего класса.

Давайте добавим статический метод, который будет нашим единственным способом использовать этот закрытый конструктор вне класса Employee:

public static Employee buildManager(String id, String name) {
    return new Employee(id, name, true);
}

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

Employee manager = Employee.buildManager("123MAN","Bob");

~ ~~ И за кулисами, конечно же, метод buildManager вызывает наш приватный конструктор.

5. Методы

Теперь добавим в наш класс приватный метод:

private void setManager(boolean manager) {
    this.manager = manager;
}

И давайте предположим, что по какой-то причине у нас в компании есть произвольное правило, в котором есть только сотрудник по имени «Карл». € можно повысить до менеджера, хотя другие классы об этом не знают. Мы создадим открытый метод с некоторой логикой для обработки этого правила, которое вызывает наш частный метод:

public void elevateToManager() {
    if ("Carl".equals(this.name)) {
        setManager(true);
    }
}

6. private in Action

Давайте посмотрим на пример того, как использовать наш класс Employee извне: ~~ ~

public class ExampleClass {

    public static void main(String[] args) {
        Employee employee = new Employee("Bob","ABC123");
        employee.setPrivateId("BCD234");
        System.out.println(employee.getPrivateId());
    }
}

После выполнения ExampleClass мы увидим его вывод на консоли:

BCD234_ID

В этом примере мы использовали публичный конструктор и публичный метод changeId(customId), потому что мы не можем получить доступ к приватной переменной privateId напрямую.

Давайте посмотрим, что произойдет, если мы попытаемся получить доступ к закрытому методу, конструктору или переменной вне нашего класса Employee:

public class ExampleClass {

    public static void main(String[] args) {
        Employee employee = new Employee("Bob","ABC123",true);
        employee.setManager(true);
        employee.privateId = "ABC234";
    }
}

Мы получим ошибки компиляции для каждого из наших недопустимых операторов:

The constructor Employee(String, String, boolean) is not visible
The method setManager(boolean) from the type Employee is not visible
The field Employee.privateId is not visible

~~ ~ 7. Классы

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

public class PublicOuterClass {

    public PrivateInnerClass getInnerClassInstance() {
        PrivateInnerClass myPrivateClassInstance = this.new PrivateInnerClass();
        myPrivateClassInstance.id = "ID1";
        myPrivateClassInstance.name = "Bob";
        return myPrivateClassInstance;
    }

    private class PrivateInnerClass {
        public String name;
        public String id;
    }
}

В этом примере мы создали закрытый внутренний класс внутри нашего PublicOuterClass, указав приватный модификатор доступа.

Поскольку мы использовали ключевое слово private, если мы по какой-то причине попытаемся создать экземпляр нашего PrivateInnerClass вне PublicOuterClass, код не скомпилируется, и мы увидим ошибку:

PrivateInnerClass cannot be resolved to a type

8. Заключение

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

Как всегда, пример кода доступен на GitHub.