17 июл. 2015 г.

Интерфейсы. Часть 5 – вложенные интерфейсы.

Интерфейс может быть объявлен членом класса или другого интерфейса. Такой интерфейс называется интерфейсом-членом или вложенным интерфейсом. Вложенный в класс интерфейс может быть объявлен как public, private или protected. Это отличает его от интерфейса верхнего уровня или интерфейса вложенного в другой интерфейс, который должен быть либо объявлен как public, либо, как уже было отмечено, должен использовать уровень доступа, заданный по умолчанию.

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

Вложенный в класс интерфейс объявленный с модификатором private не может быть имплементирован каким-либо классом. Он может использоваться только внутри того класса где был объявлен.

Ну и небольшой примерчик, который демонстрирует все вышеописанное…

package pro.java.innerintf;
import static pro.java.util.Print.*;
import pro.java.innerintf.MyInter.Myinner;
// класс А содержит вложенные интерфейсы
class A {
interface Aint1 {
default void aintPrt1() {
println("Default aintPrt1");
}
static void aintPrt2() {
println("aintPrt2 static");
}
}
private interface Apriv {
default void privPrt() {
println("privPrt() default");
}
}
protected interface Aprot {
void protPrt();
}
// внутренний класс Аа реализует Apriv
class Aa implements Apriv {
}
// метода класса А использующий внутренний класс Aa
void AaPrint() {
Aa aa = new Aa();
aa.privPrt();
}
}
// интерфейс MyInter содержит волженный интерфейс
interface MyInter {
void prt();
interface Myinner {
default void myinnerPrt() {
println("myinnerPrt default");
}
}
}
// класс B реализует вложенный интерфейс Aint
class B implements A.Aint1 {
}
// класс Bb релизует вложенный интерфейс Aprot
class Bb implements A.Aprot {
@Override
public void protPrt() {
println("aprotPrt() in Bb");
}
}
// класс С реализует вложенный интерфейс Myinner
class C implements Myinner {
}
// класс D реализует интерфейс MyInter
class D implements MyInter {
@Override
public void prt() {
println("prt() in Class D");
}
}
public class InnerIntf {
public static void main(String[] args) {
// используем статический метод вложенного интерфейса
A.Aint1.aintPrt2();
A a = new A();
a.AaPrint();
B b = new B();
b.aintPrt1();
Bb bb = new Bb();
bb.protPrt();
C c = new C();
c.myinnerPrt();
D d = new D();
d.prt();
}
}
view raw InnerIntf hosted with ❤ by GitHub

Вывод у программы следующий:

I0023

Первая строка выводится статическим методом aintPrt2() вложенного в класс А интерфейса Aint1. Вывод генерирует строка 80. Вторая строка выводится при помощи некоторый танцев с бубном, а именно при помощи метода AaPrint() вложенного класса Aa. Вложенные классы мы пока не изучали, поэтому данный бубен может быт не понятен. Далее уже все просто :) ну и по правде сказать лень расписывать подробно. Если чё, то пишите комменты :)

12 комментариев:

  1. "Вложенный в класс интерфейс объявленный с модификатором protected не может быть имплементирован каким-либо классом. Он может использоваться только внутри того класса где был объявлен." - кажется у Вас тут ошибка, нельзя имплементировать с модификатором доступа privete.

    ОтветитьУдалить
    Ответы
    1. Ошибка у вас, так как надо внимательней читать. Вы путаете protected и private в с своем же собственном тексте (комментарии).

      Удалить
    2. Кроме того вы дважды прочитали не внимательно. Вложенный в класс интерфейс объявленный с модификатором private не может быть имплементирован каким-либо классом. Ясно же сказано не может быть имплементирован.

      Удалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить
  3. Этот комментарий был удален автором.

    ОтветитьУдалить
    Ответы
    1. Во первых я сейчас в отпуске. Во вторых отвечаю на комментарии когда у меня есть время. После отпуска у меня времени особо не будет. Поэтому обещать ни чего не могу. Пишите тут, будет время отвечу.

      Удалить
  4. В 65 строке "// класс С реализует вложенный интерфейс Myinner". В данном случае возникает ошибка. "Когда вложенный интерфейс используется вне содержащей его области определения, он должен определяться именем класса или интерфейса, членом которого он является." Cтрока должна выглядеть так: "class C implements MyInter.Myinner " тогда все заработает.

    ОтветитьУдалить
    Ответы
    1. Скорее всего, Вы описали интерфейс MyInter и класс, его имплементирующий (class C implements Myinner), не в пределе одного пакета. Либо Вы не импортировали этот интерфейс. Если кинуть класс С и интерфейс MyInter в один пакет (package), а затем импортировать интерфейс, то всё будет работать.

      Удалить
  5. У меня этот код работает без всяких изменений. Почему не работет у вас и чего вы там наваяли я не знаю :)

    ОтветитьУдалить
  6. Ясно же написано: "Это отличает его от интерфейса верхнего уровня или интерфейса вложенного в другой интерфейс, который должен быть либо объявлен как public, либо, как уже было отмечено, должен использовать уровень доступа, заданный по умолчанию."

    Строка 65 абсолютно корректна, так как в данном случае интерфейс вложен в другой интерфейс и оба они имеют модификатор доступа public.

    ОтветитьУдалить
  7. Скажите пожалуйста когда необходимо использовать вложенные интерфейсы? Желательно с примером из жизни

    ОтветитьУдалить
  8. Этот комментарий был удален автором.

    ОтветитьУдалить