Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на Java.docx
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
3.45 Mб
Скачать

Тема 2.17 Введение в управление доступом

Как вы уже знаете, инкапсуляция связывает данные с манипулирующим ими кодом. Однако инкапсуляция предоставляет еще один важный атрибут: управление доступом. Посредством инкапсуляции можно управлять тем, какие части программы могут получать доступ к членам класса. Управление доступом позволяет предотвращать злоупотребления. Например, предоставляя доступ к данным только посредством четко определенного набора методов, можно предотвратить злоупотребление этими данными. Таким образом, если класс реализован правильно, он создает "черный ящик", который можно использовать, но внутренний механизм которого защищен от повреждения. Однако представленные ранее классы не полностью соответствуют этой цели.

Способ доступа к члену класса определяется спецификатором доступа, который изменяет его объявление. В Java определен обширный набор спецификаторов доступа. Некоторые аспекты управления доступом связаны главным образом с наследованием и пакетами. (Пакет – это, по сути, группирование классов.) Эти составляющие механизма управления доступом Java будут рассмотрены в последующих разделах. А пока начнем с рассмотрения применения управления доступа к отдельному классу. Когда основы управления доступом станут понятными, освоение других аспектов не представит особой сложности.

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

Начнем с определения спецификаторов public и private. Когда член класса изменяется спецификатором доступа public, он становится доступным для любого другого кода. Когда член класса указан как private, он доступен только другим членам этого же класса. Теперь вам должно быть понятно, почему методу main () всегда предшествует спецификатор public. Этот метод вызывается кодом, расположенным вне данной программы – т.е. системой времени выполнения Java. При отсутствии спецификатора доступа по умолчанию член класса считается общедоступным внутри своего класса.

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

Спецификатор доступа предшествует остальной спецификации типа члена. То есть оператор объявления члена должен начинаться со спецификатора доступа. Например:

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

Чтобы влияние использования общедоступного и приватного доступа было понятно, рассмотрим следующую программу(листинг 2.20):

Листинг 2.20

//Эта программа демонстрирует различие между спецификаторами public и private.

public class Test {

int a; // доступ, определенный по умолчанию

public int b; // общедоступный доступ

private int с; // приватный доступ

// методы доступа к с

public void setC(int i) {

// установка значения переменной с

с = i;

}

public int getC() {

// получение значения переменной с

return с;

}

}

class AccessTest {

public static void main(String args[]) {

Test ob = new Test();

// Эти операторы правильны, а и b доступны непосредственно

ob.a = 10;

ob.b = 20;

// Этот оператор неверен и может вызвать ошибку

// ob.c = 100;

// Ошибка!

// Доступ к объекту с должен осуществляться посредством методов его класса

ob.setC(100);

System.out.println("a, b, и с: " + ob.a + " " + ob.b + " " + ob.getC());

}

}

Как видите, внутри класса Test использован метод доступа, заданный по умолчанию, что в данном примере равносильно указанию доступа public. Объект b явно указан как public. Объект с указан как приватный. Это означает, что он недоступен для кода, переделенного вне его класса. Поэтому внутри класса AccessTest объект с не может применяться непосредственно. Доступ к нему должен осуществляться посредством его общедоступных методов setС () и getС (). Удаление символа комментария из начала строки:

ob.c = 100; // Ошибка!

сделало бы компиляцию этой программы невозможной из-за нарушений правил доступа.