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

Author: Tatyana Milkina
  1. Модификаторы доступа и уровни доступа
  2. Отличие уровня доступа по умолчанию, public и private
  3. Уровень доступа protected в Java
  4. Уровни доступа для класса

1. Модификаторы доступа и уровни доступа

Вы уже, наверное, неоднократно видели в примерах использование таких ключевых слов, как public, private и protected. Это модификаторы доступа в языке Java. Сегодня мы рассмотрим для чего они используются.

Очень часто в Java доступ к некоторым членам класса желательно ограничить. Для этого и нужны модификаторы доступа, которые могут присутствовать в объявлении члена класса. Модификатор доступа указывается перед остальной спецификации типа члена, например:

public int i; 
private static double j; 
private int myMethod (int а , char b ) { / / . . .

Существует три модификатора доступа: public, private и protected и четыре уровня доступа:

  1. public (открытый) - когда член объявляется с модификатором доступа public, он становится доступным из любого другого кода.
  2. private (закрытый) - когда член класса объявляется с модификатором доступа private, он доступен только другим членам этого же класса.
  3. protected (защищенный) - применяется только при наследовании.
  4. Уровень доступа, предоставляемый по умолчанию - в отсутствие модификатора доступа по умолчанию член класса считается открытым в своем пакете, но недоступным для кода, находящегося за пределами этого пакета.

Ограничение уровня доступа к членам класса - это еще один механизм реализации принципа инкапсуляции. 

2. Отличие уровня доступа по умолчанию, public и private

Рассмотрим отличие уровня доступа по умолчанию, public и private на следующем примере. В классе Modificators объявлено три переменные с разным уровнем доступа. Внутри самого класса Modificators можно обратится к любой из этих переменных, как показано в методе toString():

package oop;

public class Modificators {
    public int publicVar; // открытый уровень доступа
    private int privateVar; // закрытый уровень доступа
    int defaultVar; // уровень доступа по умолчанию

    public String toString() {
        return "Modificators{"
                + "publicVar=" + publicVar
                + ", privateVar=" + privateVar
                + ", defaultVar=" + defaultVar
                + '}';
    }
}

В классе ModificatorsDemo1, созданном в том же пакете, где и класс Modificators, объявляем объект типа Modificators и обращаемся к его public переменной и переменной с уровнем доступа по умолчанию. При попытке обратится к private переменной, возникнет ошибка компиляции - она недоступна извне класса Modificators:

package oop;

public class ModificatorsExample1 {
    public static void main(String[] args) {
        Modificators object = new Modificators();

        object.defaultVar = 10;
        object.publicVar = 20;
        //object.privateVar = 100; // Ошибка компиляции!
    }
}

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

package oop.p2;

import oop.Modificators;

public class ModificatorsExample2 {
    public static void main(String[] args) {
        Modificators object = new Modificators();

        //object.defaultVar = 10;// Ошибка компиляции!
        object.publicVar = 20;
        //object.privateVar = 100; // Ошибка компиляции!
    }
}

3. Уровень доступа protected в Java

Уровень доступа protected используется при наследовании. Он очень похож на уровень доступа по умолчанию, который раскрывает область видимости только для классов определенных в том же пакете. Protected модификатор раскрывает область видимости для классов определенных в том же пакете или для классов наследников.

Рассмотрим разницу между уровнями доступа на следующем примере.

Объявим в классе Parent три метода с разными уровнями доступа:

package oop.p1;

public class Parent {
    public void publicAccessMethod() {
    }

    void defaultAccessMethod() {
    }

    protected void protectedAccessMethod() {
    }
}

Определяем класс наследник в другом пакете:

package oop.p2;

import oop.p1.Parent;

public class Child extends Parent {
    public void someMethod() {
        publicAccessMethod();
        //defaultAccessMethod();
        protectedAccessMethod();
    }
}

Из класса Child нет доступа к default членам класса Parent, но есть доступ к protected и public членам класса Parent.

Рассмотрим следующий класс - AccessClass, находящийся в пакете отличном от класса Parent. Он не является наследником Parent, поэтому доступ из него разрешен только к public методам:

package oop.p2;

import oop.p1.Parent;

public class AccessClass {
    public static void main(String[] args) {
        Parent parent = new Parent();
        parent.publicAccessMethod();
        //  parent.defaultAccessMethod();
        // parent.protectedAccessMethod();
    }
}

Перенесем класс AccessClass в пакет, в котором находится класс Parent, и мы получим доступ не только к public членам класса, но и к protected и default:

package oop.p1;

public class AccessClass {
    public static void main(String[] args) {
        Parent parent = new Parent();
        parent.publicAccessMethod();
        parent.defaultAccessMethod();
        parent.protectedAccessMethod();
    }
}

4. Уровни доступа для класса

Для класса, не являющегося вложенным, может быть указан только один из двух возможных уровней доступа:

  • По умолчанию - если у класса имеется уровень доступа по умолчанию, такой класс оказывается доступным только для кода из данного пакета.
  • Открытый (public) - если класс объявлен как public, он доступен из любого другого кода.

Когда мы говорим, что код из одного класса (class A) имеет доступ к коду из другого класса (class B), это означает что класс A может делать одну из трех вещей:

  • создать экземпляр класса B,
  • наследовать класс B,
  • иметь доступ к определенным членам класса B.

В этом примере показана попытка наследовать класс HotBevarage с уровнем доступа по умолчанию из другого пакета. В этом случае возникнет ошибка компиляции:

package oop.p1;

class HotBeverage{}
package oop.p2;

//import oop.p1.HotBeverage;

public class Tea  //extends HotBeverage{}

Если класс оказывается открытым, он должен быть единственным открытым классом, объявленным в файле, а имя этого файла должно совпадать с именем класса. Например:

public class Beverage {}

class HotBeverage{}
Курс 'Java для начинающих' на Udemy Курс 'Java для начинающих' на Udemy
Читайте также:
Комментарии