静态/最终 java 类?

4

我希望在任何扩展了我的父类的子类中强制实现单例模式。也就是说,我只想让每个子类有一个实例存在(可以通过Child.INSTANCE或类似方式访问)。

理想情况下,我希望Child.INSTANCE对象被创建后,不再创建Parent类型的其他对象。

目前,我通过以下方式获取实例:

public class Child extends Parent {
    public static final Child INSTANCE = new Child();
    ....

我想知道,Java类是否可以以某种方式变成静态的?谢谢 =]

1
回答问题的一部分:内部类可以被声明为静态;至于问题的其他部分,我不确定你想要的是否能够实现。 - Daniel DiPaolo
1
你是想在继承树中每个类都只有一个实例,还是整个树只有一个类的实例? - Jonathan B
谢谢,我已经知道了。不幸的是,这会使我的类过长 - 而且我认为我必须将Parent设置为静态内部... - Dartoxian
这样做的目的是什么?可能有比试图强制每个子类成为单例更好的设计。 - jzd
@Jonathan 继承树中每个类只有一个实例。@jzd 这只是为了忠于状态模式,并且现有代码的某些部分(=[)依赖于他们看到的Child实例是唯一的事实。 - Dartoxian
@Dartoxian:在这种情况下,我的“枚举”解决方案正是医生所开的药方。:-) 例如,枚举非常适合表示状态机中的状态。 - C. K. Young
5个回答

9

你的子类集合是否固定?如果是,考虑使用 enum

public enum Parent {
    CHILD1 {
        // class definition goes here
    },

    CHILD2 {
        // class definition goes here
    };

    // common definitions go here
}

由于 OP 提到状态模式,这里提供两个基于 enum 的状态机示例:一个简单的示例一个复杂的示例


我预计子集将非常庞大并继续增长。 - Dartoxian
1
@Dartoxian:没错,但它是否需要在运行时增长,或者您可以重新编译?如果是后者,那么仍然适用。 - C. K. Young
1
重新编译是会发生的事情。感谢提供链接 - 看起来是一个非常有用的指针 =] - Dartoxian

1

这是可以做到的,但我不认为有必要。在我看来,你最好使用枚举。

enum {
  Singleton, 
  Child { /* override methods here * }
}

然而,为了回答你的问题,你可以采取以下方法

class SingletonParent {
   private static final Set<Class> classes = new CopyOnArraySet();
   { if (!classes.add(getClass()) throw new AssertionError("One "+getClass()+" already created."); }
}

1

你正在看错误的设计模式。

看一下工厂模式。 工厂可以创建一个类的单个实例,然后将其分配给任何想要它的人。 工厂可以分配父级、任何子级或任何其他你想要的单例。


0
你可以使用Java的enum。基本上它会创建一堆公共静态类(就像你所做的那样),但对它们进行了一些限制。
public enum Child {
   INSTANCE;
}

请注意,enums是完整的类,因此如果您希望,可以轻松地按每个实例添加方法。

0

我会回答一个我之前问过的非常相似的问题。我相信这个方法可以实现你想要的功能,但是需要遵循答案中提到的所有限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接