【问题标题】:Java: Initializing a public static field in superclass that needs a different value in every subclass instanceJava:在超类中初始化一个公共静态字段,该字段在每个子类实例中都需要不同的值
【发布时间】:2010-04-14 20:42:50
【问题描述】:

晚上好,

我正在开发一组 Java 类,以便容器类 Box 包含包含类 WidgetListWidget 需要能够指定与其他 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.WIDGETIDBox 可以遍历它的列表,将第二个参数与iter.next().getWidgetID() 进行比较。

现在,到目前为止,这一切都很好。我要做的是不必在所有子类中声明public static final WidgetID WIDGETID,而是在父类Widget 中实现它。问题是,如果我将该行代码移动到Widget(连同getWidgetID() 的实现),那么Widget 的子类的每个实例似乎都会为它们的Subclassname.WIDGETID 获得相同的static final WidgetID。但是,将其设为非静态意味着我什至不能再调用 Subclassname.WIDGETID

那么:如何在父类Widget 中创建静态WidgetID,同时确保Widget 的每个实例和Widget 的子类都不同?还是我在这里使用了错误的工具?

谢谢!

[编辑] 我不希望库的用户在所有子Widget 构造函数中调用super()

【问题讨论】:

  • WidgetID 是用来标识 Widget 的实例还是 Widget 的子类?也就是需要区分RedWidgets吗?
  • 否;假设(实际上是这样写的)Box 将只包含Widget 的每个子类的单个实例。也许我应该叫它ExclusiveBox。 :) WidgetID 将仅标识 Widget 的子类。

标签: java static initialization subclass final


【解决方案1】:

既然这个想法似乎是每个特定子类的 WidgetID 都是唯一的,那么您为什么不直接通过它们的类来识别它们呢?

所以你在getBox().addWidgetRelationship(RelationshipTypes.SomeType, RedWidget.WIDGETID) 做的地方可以用getBox().addWidgetRelationship(RelationshipTypes.SomeType, RedWidget.class) 代替。

【讨论】:

  • 我其实很喜欢这种方法;如果 Google Web Toolkit 支持这一点,那听起来很理想。你能指定一个方法只接受来自Widget或其子类的Class对象吗?例如,这样就不能通过someRandomObject.class
  • 二进制:可以,声明参数为Class<? extends Widget>
【解决方案2】:

如果每个子类都有不同的值,则该变量不是超类的成员。

换句话说,是的,每个子类都应该声明自己的 WIDGETID;您不能将各个类的成员合并为超类中的单个成员。

【讨论】:

  • 标记为正确答案,因为它回答了提出的问题,尽管其他答案提供了有用的想法。
【解决方案3】:

为什么不在 Widget 中声明一个抽象方法,例如:

protected abstract WidgetID getWidgetID();

这样,每个子类都必须实现该方法并返回自己的值。您仍然可以在子类中将 WidgetID 声明为静态,但上述实例方法返回“唯一”值。

【讨论】:

  • 使用该接口,如果您已经拥有该小部件的实例,则只能引用该小部件。在他的例子中,知道类就足够了。
  • 这个功能(杰森的原始答案)是我的问题中目前的工作方式。也许这是一个迹象。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多