Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

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

Инициализация полей интерфейсов

Поля, определяемые в интерфейсах, не могут быть «пустыми константами», но могут инициализироваться не-константными выражениями. Например:

//• interfaces/RandVals java // Инициализация полей интерфейсов // не-константными выражениями, import java.util.*;

public interface RandVals {

Random RAND = new Random(47); int RANDOM_INT = RAND.nextInt(10); long RAND0M_L0NG = RAND.nextLong * 10; float RANDOMJLOAT = RAND, next Long * 10; double RAND0M_D0UBLE = RAND.nextDouble * 10; } ///.-

Так

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

//: interfaces/TestRandVals.java import static net.mindview.util.Print.*;

public class TestRandVals {

public static void main(String[] args) { print(RandVals.RANDOMJNT); pri nt(RandVals.RAND0M_L0NG); print(RandVals.RANDOM FLOAT); pri nt(RandVa1s.RANDOM^DOUBLE);

}

} /* Output: 8

– 32032247016559954 -8.5939291E18 5.779976127815049 *///:-

Конечно, поля не являются частью интерфейса. Данные хранятся в статической области памяти, отведенной для данного интерфейса.

Вложенные интерфейсы

Интерфейсы могут вкладываться в классы и в другие интерфейсы1. При этом обнаруживается несколько весьма интересных особенностей:

//: interfaces/nesting/Nestinglnterfaces.java package interfaces.nesting;

class A {

interface В {

void f;

}

public class BImp implements В { public void f {}

private class BImp2 implements В { продолжение &

public void f {}

}

public interface С { void f;

}

class CImp implements С { public void f {}

}

private class CImp2 implements С { public void f {}

}

private interface D { void f;

}

private class DImp implements D { public void f {}

}

public class DImp2 implements D { public void f {}

}

public D getDO { return new DImp2; }

private D dRef;

public void receiveD(D d) { dRef = d; dRef.fO:

}

interface E {

interface G {

void f;

}

// Избыточное объявление public: public interface H { void f;

}

void g;

// He может быть private внутри интерфейса: //! private interface I {}

public class Nestinglnterfaces {

public class BImp implements А.В { public void f {}

}

class CImp implements А С { public void f {}

}

// Private-интерфейс не может быть реализован нигде, // кроме как внутри класса, где он был определен: //! class DImp implements A.D { //! public void f {} //! }

class EImp implements E { public void g {}

}

class EGImp implements E.G { public void f {}

}

class EImp2 implements E { public void g {} class EG implements E.G { public void f {}

}

}

public static void main(String[] args) { A a = new ), //

Нет доступа к A.D. //! A D ad = a getDO. // He возвращает ничего, кроме A.D: //! A DImp2 di2 = a getDO. // Член интерфейса недоступен //' a getDO f.

// Только другой класс А может использовать getDO А а2 = new А. а2 receiveD(a getDO).

}

} /// ~

Синтаксис вложения интерфейса в класс достаточно очевиден. Вложенные интерфейсы, как и обычные, могут иметь «пакетную» или открытую (public) видимость.

Любопытная подробность: интерфейсы могут быть объявлены закрытыми (private), как видно на примере A.D (используется тот же синтаксис описания, что и для вложенных классов). Для чего нужен закрытый вложенный интерфейс? Может показаться, что такой интерфейс реализуется только в виде закрытого (private) вложенного класса, подобного DImp, но A.DImp2 показывает, что он также может иметь форму открытого (public) класса. Тем не менее класс A.DImp2 «замкнут» сам на себя. Факт реализации private-интерфейса не может упоминаться в программе, поэтому реализация такого интерфейса — просто способ принудительного определения методов этого интерфейса без добавления информации о дополнительном типе (то есть восходящее преобразование становится невозможным).

Метод getD усугубляет сложности, связанные с private-интерфейсом, — это открытый (public) метод, возвращающий ссылку на закрытый (private) интерфейс. Что можно сделать с возвращаемым значением этого метода? В методе main мы видим несколько попыток использовать это возвращаемое значение, и все они оказались неудачными. Заставить метод работать можно только одним способом — передать возвращаемое значение некоторому объекту, которому разрешено его использование (в нашем случае это еще один объект А, у которого имеется необходимый метод receiveD).

Интерфейс Е показывает, что интерфейсы могут быть вложены друг в друга. Впрочем, правила для интерфейсов — в особенности то, что все элементы интерфейса должны быть открытыми (public), — здесь строго соблюдаются, поэтому интерфейс, вложенный внутрь другого интерфейса, автоматически объявляется открытым и его нельзя сделать закрытым (private).

Пример Nestinglnterfaces демонстрирует разнообразные способы реализации вложенных интерфейсов. Особо стоит отметить тот факт, что при реализации интерфейса вы не обязаны реализовывать вложенные в него интерфейсы. Также закрытые (private) интерфейсы нельзя реализовать за пределами классов, в которых они описываются.

Поделиться:
Популярные книги

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Не верь мне

Рам Янка
7. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Не верь мне

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Лекарь

Первухин Андрей Евгеньевич
1. Лекарь
Фантастика:
фэнтези
попаданцы
альтернативная история
7.50
рейтинг книги
Лекарь

Менталист. Конфронтация

Еслер Андрей
2. Выиграть у времени
Фантастика:
боевая фантастика
6.90
рейтинг книги
Менталист. Конфронтация

Найденыш

Шмаков Алексей Семенович
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Найденыш

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Студиозус

Шмаков Алексей Семенович
3. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Студиозус

Попаданка для Дракона, или Жена любой ценой

Герр Ольга
Любовные романы:
любовно-фантастические романы
7.17
рейтинг книги
Попаданка для Дракона, или Жена любой ценой

Шайтан Иван 2

Тен Эдуард
2. Шайтан Иван
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Шайтан Иван 2

Шайтан Иван 3

Тен Эдуард
3. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Шайтан Иван 3

Мастер 6

Чащин Валерий
6. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 6

Сын Тишайшего 4

Яманов Александр
4. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Сын Тишайшего 4

Законы Рода. Том 11

Андрей Мельник
11. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 11