如何让基类知道子类的哪些对象被创建?

时间:2013-10-21 21:42:19

标签: java constructor

我想创建一个基类和一些子类。我想让基类知道创建子类的对象。 我试图从子类的构造函数中调用基类的方法,如下所示:

class Base{
    private ArrayList<Base> subClasses;
    void addSubClassess(Base b){
        subClasses.add(b);
    }
    void calculateSubClasses(){
        System.out.println(subClasses.size());
    }
}

class Sub extends Base{
    Sub(){
        super.addSubClassess(this);
    }

}

public class Test{
    public static void main(String[] args){
        Sub s = new Sub();
        Base b = new Base();
        b.calculateSubClasses();
}

但是,上面的代码会抛出NullPointerException。我知道这是因为调用方法'addSubClassess'实际上是在创建子类之前发生的。因此该方法无法正常工作。

那么有什么方法可以解决我的问题吗? 这是一个例子来解释我到底想要什么?

有一个名为Shape的基类,它有许多子类,例如Circle,Square,Triangle。 Class Shape有一个方法名称'erase'来擦除形状,它被subClasses覆盖。 Class Shape有另一个私有方法名称'eraseAll'来擦除所有创建的形状。 因此,如果我想调用'eraseAll',我应该知道确切创建了什么,然后一次删除它们。

我希望有人可以帮助我。 非常感谢!

2 个答案:

答案 0 :(得分:1)

如果您尝试将所有Sub实例计入基类,则subClasses不能是实例变量。这将为Sub的每个实例创建一个新列表。

subClasses需要是一个静态变量,以便所有实例共享相同的列表。

private static java.util.ArrayList<Base> subClasses = new java.util.ArrayList<Base>();

通过静态初始化列表,Base构造函数不需要创建subClasses ArrayList的新实例。

答案 1 :(得分:1)

此样本适合您吗?将为任何子类构造函数调用此匿名块,并将计数器放入映射中。

如果您需要单个基本实例,则应删除单词static


public class Base{
  private static final Map<Class, Integer> counters = new HashMap();

  {
     synchronized(counters){
        Integer v = counters.get(getClass());
        v = v == null ? 0 : v;
        counters.put(getClass(), v + 1);  
     }
  }
}