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

причина, по которой вы можете использовать этот метод, заключается в том, что интерфейс является локальным для пакета. Попробуйте сделать это публичным.

Другие вопросы по тегам