Перечисления: методы, исключающие каждый из экземпляров - PullRequest
19 голосов
/ 01 июля 2011

Из другой вопрос Я узнал, что в Java возможно определить конкретные методы для каждого из экземпляров Enum :

public class AClass {

    private enum MyEnum{
        A { public String method1(){ return null; } },
        B { public Object method2(String s){ return null; } },
        C { public void method3(){ return null; } } ;
    }

    ...
}

Я был удивлен, что это даже возможно, есть ли у «исключительных методов», специфичных для каждого экземпляра, имя для поиска документации?

Кроме того, как это должно бытьиспользуется ?Потому что следующее не компилируется:

    private void myMethod () {
        MyEnum.A.method1();
    }

Как я должен использовать эти "эксклюзивные" методы?

Ответы [ 3 ]

18 голосов
/ 01 июля 2011

Вам необходимо объявить абстрактные методы в вашем перечислении, которые затем будут реализованы в определенных экземплярах перечисления.

class Outer {

    private enum MyEnum {
        X {
            public void calc(Outer o) {
                // do something
            }
        },
        Y {
            public void calc(Outer o) {
                // do something different
                // this code not necessarily the same as X above
            }
        },
        Z {
            public void calc(Outer o) {
                // do something again different
                // this code not necessarily the same as X or Y above
            }
        };

        // abstract method
        abstract void calc(Outer o);
    }

    public void doCalc() {
        for (MyEnum item : MyEnum.values()) {
            item.calc(this);
        }
    }
}
14 голосов
/ 01 июля 2011

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

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

(*) Часть JLS 8.9 перечисления говорит: «Необязательное тело класса константы перечисления неявно определяет объявление анонимного класса (§15.9.5), которое расширяет непосредственно включающий тип перечисления».

5 голосов
/ 01 июля 2011

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

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

Я использовал эту технику, чтобы значительно уменьшить сложность кода в операторах switch. Вместо того, чтобы включать перечисление в каком-то другом классе, просто получите ссылку на него и вызовите метод, и пусть само перечисление позаботится об этом. Конечно, это зависит от сценария, если он имеет смысл, но он может значительно снизить сложность кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...