1

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

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。形状类有一个方法名称“erase”来擦除形状,它被子类覆盖。类 Shape 有另一个私有方法名称“eraseAll”来擦除所有创建的形状。因此,如果我想调用“eraseAll”,我应该知道究竟创建了什么,然后一次删除它们。

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

4

2 回答 2

1

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

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

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

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

于 2013-10-21T22:03:35.550 回答
1

这个样本对你有用吗?将为任何子类构造函数调用此匿名块,并将计数器放入映射中。

如果您需要对单个基本实例使用此功能,static则应删除 word。


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);  
     }
  }
}

于 2013-10-21T22:18:25.587 回答