超类可以静态地将其子类存储在列表中吗?

时间:2014-03-18 18:03:36

标签: java inheritance static

我有一个超类,SuperClass。我想要一个显示SuperClass的每个子类的JList。不是实例化了多少个SuperClass的子类,而是我在程序中实际定义了多少个子类。关键是,在不改变代码的情况下添加新的子类应该很容易。

我希望我的SuperClass可以为我定义的每个子类(不是实例化)定义一个静态映射。现在,通过单击JList的项目,应该实例化相应的子类。

我会尝试展示我想做的事情:

public abstract class SuperClass {
    protected static ArrayList<?extends SuperClass> subclasses = new ArrayList<>();
}
class SubClassOne extends SuperClass {
    static {
        subclasses.add(this)
    }
}

现在我意识到上面的代码有很多问题,但我希望它能澄清我想要的东西。关于从JList实例化我的子类,我完全不知道如何处理。

请说明我是否可以提供更多可能有帮助的信息。

3 个答案:

答案 0 :(得分:0)

您可以在子类中使用静态初始化程序块:

public class MySubclass extends MySuperclass {

    static {
        MySuperclass.register(MySubclass.class);
    }
}

然后在您的超类中,您可以使用register方法:

protected static void reigster(Class<?> clazz) {
    subclasses.add(clazz);
}

然后当你想要实例化一个类时:

MySuperclass subclassInstance = subclasses.get(someIndex).newInstance();

请注意,这仅适用于您实际加载这些类的情况。对于动态类加载,您可能必须实现自己的ClassLoader或使用一些动态OSGi框架,如Apache Felix。

答案 1 :(得分:0)

方法1:

public abstract class SuperClass {
    protected static ArrayList<Class<? extends SuperClass>> subclasses = new ArrayList<>();
}
class SubClassOne extends SuperClass {
    static {
        subclasses.add(SubClassOne.class);
    }
 }

方法2

扫描整个类路径(使用反射),迭代每个类并检查该类是否继承自您的超类。
你可以看看Reflections library。我会以一种简单的方式为你做这件事。

希望这有帮助。

答案 2 :(得分:0)

正如其他答案所示,它不适合继承。而是查看 factory 模式:一些工厂类(包含一个类的映射),它可以实例化其中一个类的对象。

Java中有一些标准机制。

  1. 你可以制作自己的注释;使用注释处理

    @Factored
    public class A {
    }
    
    @Factored
    public class B {
    }
    

    这是一个很大的编码开销。

  2. 您可以使用java 服务提供商界面

    此SPI用于检测XML解析器等,其中类路径上的jar文件在MANIFEST下具有文件,文件名为接口类路径。 其中可以列出一个或多个实现类。然后可以列出这些实现。

    这是一种陈述性方法,因此缺乏理想的自动性。

  3. 制作工厂枚举

    仅适用于有限的近距离世界类,同时也提供强大的依赖性。

    public enum Factory<T> {
        F_A(A.class),
        F_B(B.class);
    
        private static final Set<Class<T>> klasses = new HashSet<>();
        static {
            for (Factory f : values()) {
                klasses.add(f.klass);
            }
        }
    
        public final Class<T> klass;
    
        private Factory(Class<T> klass) {
            this.klass = klass;
        }
    
        //public <S extends T> S instantiate(Class<S> kl) {
        public T instantiate() {
            ...
        }
    }