Java. Урок 22. Модификаторы доступа

Уроки для начинающих   25 Январь 2013  Автор статьи:  

В данном уроке мы рассмотрим модификаторы доступа и поговорим о том, когда следует применять их. Для чего нужны модификаторы видимости? Они нужны для того, чтобы разграничивать методы и поля на те, которые может использовать программист в определенных ситуациях и на которые не может. Существуют четыре модификатора:

  • private
  • protected
  • internal
  • public
private

Самый жесткий модификатор доступа — private. Он разрешает доступ к членам класса только из этого класса:

1
2
3
4
5
6
7
8
9
10
11
public class User {
    private int age;//поле с модификатором private

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Как вы могли заметить я создал две функции get и set, которые свободно могут обращаться к полю age. Теперь через них можно получить и задать значение переменной. Такой подход достаточно популярен при разработке программ, так как вы в этих функциях можете контролировать диапазон присваиваемых значений и корректно вернуть значение, в случае, если оно у вас явно не хранится или если оно не правильно проинициализированно:

1
2
3
4
5
6
7
8
9
10
11
public class User {
    private int age;//поле

    public int getAge() {
        return (age>0)? age : 0;//если возраст больше 0, то возвращаем его, иначе возвращаем ноль
    }

    public void setAge(int age) {
        this.age = (age>0)? age : 0;//если устанавливаемый возраст больше 0, то присваиваем его в переменную
    }
}

В данном примере, я проверяю возраст пользователя перед тем как присвоить или перед тем как вернуть значение. С таким же успехом сюда можно было добавить какую — нить проверку на null.
Рассмотрим примеры использования класса:

1
2
3
4
User user = new User();
user.age = 18;//ошибка доступа
user.setAge(-128);
int age = user.getAge();

Если бы мы не обрабатывали значение поля age в get и set, то мы получили отрицательный возраст, который мог бы привести к неправильной работе программы. Так как age имеет модификатор видимости private, то мы не можем явно установить значение перемение или получить ее значение.
Использование get-теров и set-ов желательно при создании переменных в классе, так как это единственный способ доступа к переменным private, то в среде существует способ создания их автоматически. Для этого необходимо нажать alt+insert как и в случае c конструкторами просто выбрать для каких переменных вы хотите создать get и set методы.

protected

Данный модификатор доступа разрешает использовать переменные в классах наследниках.
Допустим у нас есть тот же класс пользователь:

1
2
3
public class User {
    protected int age;
}

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

1
2
3
4
5
public class Student extends User{
    public int getGroup(){
        return (age - 18) * 100;
    }
}

Очевидно, что модификатор доступа protected является более слабым, чем private, поэтому все возможности private присутствуют и у него.

internal (default)
1
2
3
4
Данный модификатор видимости используется как модификатор доступа по умолчанию:
public class User {
    int age;
}

С помощью него можно осуществлять доступ внутри одного пакета. Пакет — это некоторый аналог папки в Java. По умолчанию все классы, которые вы создаете находятся в пакете по умолчанию, поэтому вы имеете доступ к переменным типа internal без проблем. Более подробно о пакетах мы поговорим в следующих уроках.

public

Самый приятный модификатор доступа. Он позволяет иметь доступ откуда угодно. Поэтому методы get и set и прочие функции, которые должен вызывать пользователь объекта делают public. Функции, которые должны быть использованы только как вспомогательные для класса и все поля делают private, кроме некоторых случаев, когда их делают protected.

  • DragonRei

    Во втором примере где есть условия, думаю лучше будет добавить комнтарии к каждой функции get и set с пояснением, что она делает, так мне кажется будет немного понятней.

    • http://cybern.ru/ lordrp

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

      • DragonRei

        Спасибо, стало понятней.

  • Стас

    Ну а что ж не рассказали про модификатор «internal»? Первый раз слышу.

    • http://cybern.ru/ lordrp

      Это модификатор по умолчанию.(Т.е когда ничего не указываешь это internal). Дает доступ из всех классов внутри пакета.

  • Baydin Konstantin

    В последнем блоке кода кусок html вылез.

    • http://cybern.ru/ lordrp

      Исправил.

  • Andreev Alexandr

    Почему-то к переменной Private могу обращаться через методы родителя в классе наследнике.
    Как я понял из текста, это не нормально.

    Или речь идёт о невозможности неявного присвоения?

    В переменные типа Private вообще присваиваются явно в классах наследниках.

    В чём тогда смысл public? Что значит «что угодно и откуда угодно»?
    Ведь полями класса могут пользоваться в любом случае только сам класс и его потомки?

  • Олег

    Хорошо написано. Откуда брали информацию про модификаторы доступа, отсюда http://proglang.su/java/143?

Научиться программировать

  • на Delphi

  • на Java

  • на C++