2010-04-14 2 views
1

Добрый вечер,Java: Инициализация публичного статического поля в суперкласса, который нуждается другое значение в каждом подклассе, например

Я разрабатываю набор классов Java, так что контейнер класса Box содержит List из содержимого класса Widget , A 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(); 

} 

так sublcasses из 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.

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

Спасибо!

[Изменить] Я бы предпочел не требовать от пользователей библиотеки для вызова super() во всех своих конструкторах sub.

+1

Возможно ли, что WidgetID идентифицирует экземпляр виджета или подкласс Widgets? То есть вам нужно отличить RedWidgets? – meriton

+0

Нет; предполагается, что (фактически, написано так, что) «Коробка» будет содержать только один экземпляр каждого подкласса «Виджет». Возможно, я должен был бы назвать его «Эксклюзивный бокс».:) 'WidgetID' будет идентифицировать только подкласс' Widget'. –

ответ

4

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

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

+0

Отмечено как правильный ответ, так как он отвечает на предложенный вопрос, хотя другие ответы дают полезные идеи. –

5

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

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

+0

Мне действительно нравится этот метод; если Google Web Toolkit поддерживает это, это звучит идеально. Можете ли вы указать, что метод должен принимать только объекты класса, которые поступают из 'Widget' или его подклассов? Например, чтобы нельзя было переходить в 'someRandomObject.class'? –

+2

Двоичный: Да, объявите параметр как «Класс ' – meriton

0

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

protected abstract WidgetID getWidgetID(); 

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

+0

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

+0

Эта функциональность (оригинальный ответ Джейсона) заключается в том, как сейчас работают в моем вопросе. Возможно, это знак. :) –