Enum реализующий интерфейс, интерфейс и видимость метода
Я просто наткнулся на следующий код, который меня немного удивил, хотя я и преобразовал его в простой SSCEE:
custompackage.package1.MyEnum.java
public enum MyEnum implements MyInterface {
CONSTANT_ONE() {
@Override
public void myMethod() {
//do something very interesting
}
},
CONSTANT_TWO() {
@Override
public void myMethod() {
//do something very interesting
}
};
}
interface MyInterface {
void myMethod();
}
Теперь из этого пакета я могу сделать следующее:
Consumer<MyEnum> myMethod = MyEnum::myMethod;
Однако я не могу использовать MyInterface
на все, что я понимаю, как это пакетно-частный для custompackage.package1
,
Я не понимаю, что именно происходит, кажется, MyEnum
получил myMethod()
метод добавлен, но не реализован (извне) MyInterface
,
Как это работает?
3 ответа
Ну ты не видишь MyInterface
снаружи пакет, как вы сказали, - но MyEnum
эффективно имеет публичный реферат myMethod()
метод, который вы можете использовать в качестве ссылки на метод.
Оставляя в стороне новые модные функции Java 8, это действительно (даже вне пакета):
// Even MyEnum x = null; will compile, but obviously fail
MyEnum x = MyEnum.CONSTANT_ONE;
x.myMethod();
Метод наследуется от интерфейса, даже если сам интерфейс не виден.
Это также не относится к интерфейсам и перечислениям. Например:
// Foo.java
package foo;
class SuperFoo {
public void publicMethod() {
}
}
public class Foo extends SuperFoo {
}
// Bar.java
package bar;
import foo.Foo;
public class Bar {
public void test() {
Foo foo = new Foo();
foo.publicMethod();
}
}
Это прекрасно компилируется, хотя Foo
даже не отменяет publicMethod
, Так далеко как Bar
обеспокоен, он наследуется откуда- то, но он не знает, где!
Однако я вообще не могу использовать MyInterface, что, как я понимаю, является частным для пакета custompackage.package1.
Интерфейс является закрытым для пакета, но все методы (и поля) являются (неявными или явными) открытыми.
похоже, что MyEnum добавил метод myMethod(), но он не реализует (извне) MyInterface.
MyEnum
имеет публичный метод под названием myMethod()
независимо от того, унаследовал ли он (открытый) абстрактный метод от интерфейса или объявил сам метод. Говорят иначе, даже если снаружи не видно интерфейса, снаружи наверняка можно увидеть MyEnum
и посмотреть MyEnum.myMethod()
,
В интерфейсах методы есть public abstract
по умолчанию. поля public static final
причина, по которой вы можете использовать этот метод, заключается в том, что интерфейс является локальным для пакета. Попробуйте сделать это публичным.