Основы программирования на Java - С. Сухов
Шрифт:
Интервал:
Закладка:
2. не подклассы в том же пакете;
3. подклассы в различных пакетах;
4. классы, которые не являются подклассами и не входят в тот же пакет.
В языке Java имеется три уровня доступа, определяемых ключевыми словами: private (закрытый), public (открытый) и protected (защищенный), которые употребляются в различных комбинациях. Содержимое ячеек таблицы определяет доступность переменной с данной комбинацией модификаторов (столбец) из указанного места (строка).
Есть несколько правил, которые помогут вам разобраться. Элемент, объявленный public, доступен из любого места. Все, что объявлено private, доступно только внутри класса и нигде больше. Если у элемента вообще не указан модификатор уровня доступа, то такой элемент будет виден из подклассов и классов того же пакета. Именно такой уровень доступа используется в языке Java по умолчанию. Если необходимо, чтобы элемент был доступен только подклассам, причем независимо от того, находятся ли они в данном пакете или нет — используйте protected.
Таблица 8.1 Таблица ограничения доступа
private
модификатор отсутствует
protected
public
тот же класс
да
да
да
да
подкласс в том же пакете
нет
да
да
да
независимый класс в том же пакете
нет
да
да
да
подкласс в другом пакете
нёт
нет
да
да
независимый класс в другом пакете
нет
нет
нет
да
8.2. ИнтерфейсыИнтерфейсы Java созданы для поддержки динамического выбора (resolution) методов во время выполнения программы. Интерфейсы похожи на классы, но в отличие от последних у интерфейсов нет переменных представителей, а в объявлениях методов отсутствует реализация. Класс может иметь любое количество интерфейсов. Все, что нужно сделать — это реализовать в классе полный набор методов всех интерфейсов. Сигнатуры таких методов класса должны точно совпадать с сигнатурами методов реализуемого в этом классе интерфейса. Интерфейсы обладают своей собственной иерархией, не пересекающейся с классовой иерархией наследования. Это дает возможность реализовать один и тот же интерфейс в различных классах, никак не связанных по линии иерархии классового наследования. Именно в этом и проявляется главная сила интерфейсов.
8.2.1. Оператор interfaceОпределение интерфейса сходно с определением класса, отличие состоит в том, что в интерфейсе отсутствуют объявления данных и конструкторов. Общая форма интерфейса приведена ниже:
interface имя {
тип_результата имя_метода1 (список параметров);
тип имя_finall_переменной = значение;
}
Обратите внимание — у объявляемых в интерфейсе методов отсутствуют операторы тела. Объявление методов завершается символом «;» (точка с запятой). В интерфейсе можно объявлять и переменные, при этом они неявно объявляются переменными типа final. Это означает, что класс реализации не может изменять их значения. Кроме того, при объявлении переменных в интерфейсе их обязательно нужно инициализировать константными значениями. Ниже приведен пример определения интерфейса, содержащего единственный метод с именем callback и одним параметром типа int.
interface Callback {
void callback(int param); }
8.2.2. Оператор implementsОператор implements — это дополнение к определению класса, реализующего некоторый интерфейс.
class имякласса [extends суперкласс]
[implements интерфейс0 [, интерфейс 1...]]
{тело класса}
Если в классе реализуется несколько интерфейсов, то их имена разделяются запятыми. Ниже приведен пример класса, в котором реализуется определенный нами интерфейс:
class Client implements Callback {
void callback(int p) {
System.out.println("callback вызван с " + p);
}
}
В очередном примере метод callback интерфейса, определенного ранее, вызывается через переменную-ссылку на интерфейс:
class Testlface {
public static void main(String args[])
{
switch(result) {
case NO:
System.out.println("Heт");
break;
case YES:
System.out.println("Дa");
break;
case MAYBE:
System.out.println("Moжeт быть");
break;
case LATER:
System.out.println("Позже");
break;
case SOON:
System.out.priniln("Cкopo");
break;
case NEVER:
System.out.println("Никогда");
break;
}
}
public static void main(String args[]) {
Question q = new Question();
answer(q.ask());
answer(q.ask());
answer(q.ask());
answer(q.ask());
}
}
Обратите внимание на то, что результаты при разных запусках программы отличаются, поскольку в ней используется класс генерации случайных чисел Random пакета java.util.
Позже
Скоро
Нет
Да
9. ОБРАБОТКА ИСКЛЮЧЕНИЙ
Исключение в Java — это объект, который описывает исключительное состояние, возникшее в каком-либо участке программного кода. Когда возникает исключительное состояние, создается объект класса Exception. Этот объект пересылается в метод, обрабатывающий данный тип исключительной ситуации. Исключения могут возбуждаться и «вручную» для того, чтобы сообщить о некоторых нештатных ситуациях.
9.1. Основы механизма исключенийК механизму обработки исключений в Java имеют отношение 5 ключевых слов: — try, catch, throw, throws и finally. Схема работы этого механизма следующая. Вы пытаетесь (try) выполнить блок кода, и, если при этом возникает ошибка, система возбуждает (throw) исключение, которое в зависимости от его типа вы можете перехватить (catch) или передать умалчиваемому (finally) обработчику.
Ниже приведена общая форма блока обработки исключений.
try {
// блок кода}
catch (ТипИсключения1 е) {
// обработчик исключений типа ТипИсключения1 }
catch (ТипИсюпочения2 е) {
// обработчик исключений типа ТипИсключения2
throw(e) // повторное возбуждение исключения }
finally { }
9.2. Типы исключенийВ вершине иерархии исключений стоит класс Throwable. Каждый из типов исключений является подклассом класса Throwable. Два непосредственных наследника класса Throwable делят иерархию подклассов исключений на две различные ветви. Один из них — класс Exception — используется для описания исключительных ситуаций, которые должны перехватываться программным кодом пользователя. Другая ветвь дерева подклассов Throwable — класс Error, который предназначен для описания исключительных ситуаций, которые при обычных условиях не должны перехватываться в пользовательской программе.
9.3. Неперехваченные исключенияОбъекты-исключения автоматически создаются исполняющей средой Java в результате возникновения определенных исключительных состояний. Например, очередная наша программа содержит выражение, при вычислении которого возникает деление на нуль.
class Ехс0 {
public static void main(string args[]) {
int d = 0;
int a = 42 / d;
}
}
Вот вывод, полученный при запуске нашего примера.
C:>javaExc0
java.lang. ArithmeticException: / деление на ноль
at Exc0.main(Exc0.java:4)
Обратите внимание на тот факт, что типом возбужденного исключения был не Exception и не Throwable. Это подкласс класса Exception, а именно: ArithmeticException, поясняющий, какая ошибка возникла при выполнении программы. Вот другая версия того же класса, в которой возникает та же исключительная ситуация, но на этот раз не в программном коде метода main.
class Exc1 {
static void subroutine() {
int d = 0;
int a= 10 / d;
}
public static void main(String args[]) {
Exc1 .subroutine();
}
}
Вывод этой программы показывает, как обработчик исключений исполняющей системы Java выводит содержимое всего стека вызовов.
С:> java Excl
java.lang.ArithmeticException: / деление на ноль
at Excl.subroutine(Excl.java:4)
at Excl.main(Excl.java:7)
9.4. Операторы try и catchДля задания блока программного кода, который требуется защитить от исключений, используется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения, которое вы хотите обрабатывать.
class Ехс2 {
public static void main(String args[]) {
try {
int d = 0;
int a = 42 / d;
}
catch (ArithmeticException e) {
System.out.println("деление на ноль");
}
}
}
Целью большинства хорошо сконструированных catch-разделов должна быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние — такое, чтобы программу можно было продолжить, будто никакой ошибки и не было (в нашем примере выводится предупреждение - «деление на ноль»).