我想创建一个基类和一些子类。我想让基类知道创建子类的对象。 我试图从子类的构造函数中调用基类的方法,如下所示:
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',我应该知道确切创建了什么,然后一次删除它们。
我希望有人可以帮助我。 非常感谢!
答案 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);
}
}
}