Литмир - Электронная Библиотека
Содержание  
A
A

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

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

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

Если все классы в программе относятся к одному пакету, то отсутствие модификатора доступа равнозначно указанию модификатора public по умолчанию. Пакет представляет собой группу классов, предназначенных как для организации классов, так и для управления доступом. Рассмотрение пакетов откладывается до главы 8, а для примеров программ, представленных в этой и предыдущих главах, тип доступа по умолчанию не отличается от public.

Модификатор доступа указывается перед остальной частью описания типа отдельного члена класса. Это означает, что именно с него должен начинаться оператор объявления члена класса. Ниже приведены соответствующие примеры.public String errMsg;private accountBalance bal;private boolean isError(byte status) { // ...

Для того чтобы стал понятнее эффект от применения модификаторов доступаpublic и private, рассмотрим следующий пример программы:// Открытый и закрытый доступ к членам класса,class MyClass { private int alpha; // закрытый доступ public int beta; // открытый доступ int gamma; // тип доступа по умолчанию (по существу, открытый) /* Методы доступа к переменной alpha. Члены класса могут обращаться к закрытым членам того же класса. */ void setAlpha(int а) { alpha = а; } int getAlpha() { return alpha; }}class AccessDemo { public static void main(String args[]) { MyClass ob = new MyClass(); /* Доступ к переменной alpha возможен только с помощью специально предназначенных для этой цели методов. */ ob.setAlpha(-99); System.out.println("ob.alpha is " + ob.getAlpha()); // Обратиться к переменной alpha так, как показано ниже, нельзя. // ob.alpha =10; // Ошибка! alpha - закрытая переменная! // Следующие обращения вполне допустимы, так как // переменные beta и gamma являются открытыми, ob.beta = 88; ob.gamma = 99; }}

Нетрудно заметить, что в классе MyClass переменная alpha определена как private, переменная beta — как public, а перед переменной gamma модификатор доступа отсутствует, т.е. в данном примере она ведет себя как открытый член класса, которому по умолчанию присваивается модификатор доступа public. Переменная alpha закрыта, и поэтому к ней невозможно обратиться за пределами ее класса. Следовательно, в классе AccessDemo нельзя пользоваться переменной alpha непосредственно. Доступ к ней организуется с помощью открытых методов доступа setAlpha () и getAlpha (), определенных в одном с ней классе. Если удалить комментарии в начале следующей строки кода, то скомпилировать рассматриваемую здесь программу не удастся:// ob.alpha = 10; // Ошибка! alpha - закрытая переменная!

Компилятор выдаст сообщение об ошибке, связанной с нарушением правил доступа. Несмотря на то что переменная alpha недоступна для кода за пределами класса MyClass, пользоваться ею можно с помощью открытых методов доступа setAlpha () и getAlpha ().

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

Рассмотрим практическое применение средств управления доступом на примере приведенной ниже программы. Во время ее выполнения предотвращается возникновение ошибок нарушения границ отказоустойчивого целочисленного массива. Это достигается следующим образом. Массив объявляется как закрытый член класса, а доступ к нему осуществляется с помощью специально предназначенных для этой цели методов. Эти методы отслеживают попытки обращения к элементам, не входящим в массив, и вместо аварийной остановки программы возвращают сообщение об ошибке. Массив определяется в классе FailSof tArray, код которого приведен ниже./* В этом классе реализуется отказоустойчивый массив, предотвращающий ошибки при выполнении программы.*/class FailSoftArray { private int a[]; // Ссылка на массив. private int errval; // Значение, возвращаемое в том случае, если // в методе get() будет обнаружена ошибка, public int length; // Переменная length открыта. /* Конструктору данного класса передается размер массива и значение, которое должен возвращать метод get () при обнаружении ошибки. */ public FailSoftArray(int size, int errv) { a = new int[size]; errval = errv; length = size; } // возвратить значение элемента массива по заданному индексу public int get(int index) { // Отслеживание попытки обращения за границы массива. if(ok(index)) return a[index]; return errval; } // установить значение элемента no заданному индексу, // если возникнет ошибка, возвратить логическое значение false public boolean put(int index, int val) { // Отслеживание попытки обращения эа границы массива. if(ok(index)) { a[index] = val; return true; } return false; } // возвратить логическое значение true, если индекс // не выходит за границы массива private boolean ok(int index) { if(index >= 0 & index < length) return true; return false; }}// продемонстрировать обращение к отказоустойчивому массивуclass FSDemo { public static void main(String args[]) { FailSoftArray fs = new FailSoftArray(5, -1); int x; // выявить скрытые сбои при обращении к массиву System.out.println("Fail quietly.") ; for(int i=0; i < (fs.length * 2); i++) // Доступ к массиву должен осуществляться с помощью // специально предназначенных для этого методов, fs.put(i, i*10); for (int i=0; i < (fs.length * 2); i++) { // Доступ к массиву должен осуществляться с помощью // специально предназначенных для этого методов. х = fs.get (i); if(x != -1) System.out.print(x + " "); } System.out.println ("") ; // а теперь обработать сбои и вывести сообщения об ошибках System.out.println("\nFail with error reports."); for (int i=0; i < (fs.length * 2); i++) if (!fs.put(i, i*10)) System.out.println("Index " + i + " out-of-bounds"); for(int i=0; i < (fs.length * 2); i++) { x = fs.get (i); if(x != -1) System.out.print(x + " ") ; else System.out.println("Index " + i + " out-of-bounds"); } }}

Выполнение этой программы дает следующий результат:Fail quietly.0 10 20 30 40Fail with error reports.Index 5 out-of-boundsIndex 6 out-of-boundsIndex 7 out-of-boundsIndex 8 out-of-boundsIndex 9 out-of-bounds0 10 20 30 40 Index 5 out-of-boundsIndex 6 out-of-boundsIndex 7 out-of-boundsIndex 8 out-of-boundsIndex 9 out-of-bounds

Рассмотрим подробнее приведенный выше пример программы. В классеFail So ft Array определены три закрытых члена. Первым из них является перемен¬ная а, в которой содержится ссылка на массив, предназначенный для хранения данных.Вторым членом является переменная errval, в которой хранится значение, возвращае¬мое вызывающей части программы в том случае, если вызов метода get () оказывает¬ся неудачным. И третьим членом является метод ok (), в котором определяется, нахо¬дится ли индекс в границах массива. Эти три члена могут быть использованы толькодругими членами класса FailSof tArray. Остальные члены данного класса объявленыоткрытыми и могут быть вызваны из любой части программы, где используется классFailSoftArray.

44
{"b":"242519","o":1}