Java: Инициализация открытого статического поля в суперклассе, для которого требуется различное значение в каждом экземпляре подкласса - PullRequest
2 голосов
/ 15 апреля 2010

Добрый вечер,

Я разрабатываю набор классов Java, чтобы контейнерный класс Box содержал List отдельного класса Widget. Widget должен иметь возможность указывать отношения с другими Widgets. Я подумал, что хороший способ сделать это - сделать что-то вроде этого:

public abstract class Widget {
    public static class WidgetID {
        // implementation stolen from Google's GWT
        private static int nextHashCode;
        private final int index;

        public WidgetID() {
            index = ++nextHashCode;
        }

        public final int hashCode() {
            return index;
        }
    }

    public abstract WidgetID getWidgetID();

}

чтобы подклассы Widget могли:

public class BlueWidget extends Widget {
    public static final WidgetID WIDGETID = new WidgetID();

    @Override
    public WidgetID getWidgetID() {
        return WIDGETID;
    }
}

Теперь BlueWidget может выполнять getBox().addWidgetRelationship(RelationshipTypes.SomeType, RedWidget.WIDGETID, а Box может перебирать свой список, сравнивая второй параметр с iter.next().getWidgetID().

Теперь все это прекрасно работает. Я пытаюсь не объявлять public static final WidgetID WIDGETID во всех подклассах и реализовывать его вместо этого в родительском Widget классе. Проблема в том, что если я переместу эту строку кода в Widget (вместе с реализацией getWidgetID()), то каждый экземпляр подкласса Widget, похоже, получит одинаковые static final WidgetID для своих Subclassname.WIDGETID. Однако, делая его нестатичным, я больше не могу звонить Subclassname.WIDGETID.

Итак: как создать статический WidgetID в родительском классе Widget, при этом гарантируя, что он различен для каждого экземпляра Widget и подклассов Widget? Или я использую не тот инструмент для работы здесь?

Спасибо!

[Редактировать] Я бы предпочел не требовать, чтобы пользователи библиотеки вызывали super() во всех своих под-Widget конструкторах.

Ответы [ 3 ]

5 голосов
/ 15 апреля 2010

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

Так что, где вы делаете getBox().addWidgetRelationship(RelationshipTypes.SomeType, RedWidget.WIDGETID), вы можете вместо этого сделать getBox().addWidgetRelationship(RelationshipTypes.SomeType, RedWidget.class).

4 голосов
/ 15 апреля 2010

Если у каждого подкласса есть свое значение, переменная не является членом суперкласса.

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

0 голосов
/ 15 апреля 2010

Почему бы просто не объявить абстрактный метод в Widget, например:

protected abstract WidgetID getWidgetID();

Таким образом, каждый подкласс должен реализовывать метод и возвращать свое собственное значение. Вы все еще можете объявить WidgetID как статический внутри подклассов, но вышеупомянутый метод экземпляра возвращает «уникальное» значение.

...