Интерфейс может быть объявлен членом класса или другого интерфейса. Такой интерфейс называется интерфейсом-членом или вложенным интерфейсом. Вложенный в класс интерфейс может быть объявлен как 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(); | |
} | |
} |
Вывод у программы следующий:
Первая строка выводится статическим методом aintPrt2() вложенного в класс А интерфейса Aint1. Вывод генерирует строка 80. Вторая строка выводится при помощи некоторый танцев с бубном, а именно при помощи метода AaPrint() вложенного класса Aa. Вложенные классы мы пока не изучали, поэтому данный бубен может быт не понятен. Далее уже все просто :) ну и по правде сказать лень расписывать подробно. Если чё, то пишите комменты :)
"Вложенный в класс интерфейс объявленный с модификатором protected не может быть имплементирован каким-либо классом. Он может использоваться только внутри того класса где был объявлен." - кажется у Вас тут ошибка, нельзя имплементировать с модификатором доступа privete.
ОтветитьУдалитьОшибка у вас, так как надо внимательней читать. Вы путаете protected и private в с своем же собственном тексте (комментарии).
УдалитьКроме того вы дважды прочитали не внимательно. Вложенный в класс интерфейс объявленный с модификатором private не может быть имплементирован каким-либо классом. Ясно же сказано не может быть имплементирован.
УдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьВо первых я сейчас в отпуске. Во вторых отвечаю на комментарии когда у меня есть время. После отпуска у меня времени особо не будет. Поэтому обещать ни чего не могу. Пишите тут, будет время отвечу.
УдалитьВ 65 строке "// класс С реализует вложенный интерфейс Myinner". В данном случае возникает ошибка. "Когда вложенный интерфейс используется вне содержащей его области определения, он должен определяться именем класса или интерфейса, членом которого он является." Cтрока должна выглядеть так: "class C implements MyInter.Myinner " тогда все заработает.
ОтветитьУдалитьСкорее всего, Вы описали интерфейс MyInter и класс, его имплементирующий (class C implements Myinner), не в пределе одного пакета. Либо Вы не импортировали этот интерфейс. Если кинуть класс С и интерфейс MyInter в один пакет (package), а затем импортировать интерфейс, то всё будет работать.
УдалитьУ меня этот код работает без всяких изменений. Почему не работет у вас и чего вы там наваяли я не знаю :)
ОтветитьУдалитьЯсно же написано: "Это отличает его от интерфейса верхнего уровня или интерфейса вложенного в другой интерфейс, который должен быть либо объявлен как public, либо, как уже было отмечено, должен использовать уровень доступа, заданный по умолчанию."
ОтветитьУдалитьСтрока 65 абсолютно корректна, так как в данном случае интерфейс вложен в другой интерфейс и оба они имеют модификатор доступа public.
Скажите пожалуйста когда необходимо использовать вложенные интерфейсы? Желательно с примером из жизни
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалить