我想知道我是否可以用一个抽象基类的提取方法的结果初始化一个final字段,这将由派生类实现。我知道派生的ctor会先调用基类ctor,所以我保证abtract方法的实现也只依赖于派生类的声明时定义的final字段。我尝试了下面的代码,它似乎工作。
abstract class Base {
protected final String name = calName();
protected abstract String calName();
}
public final class Foo extends Base {
private final String id = "42";
@Override
protected String calName() {
return String.format("WithId%s", id);
}
public void display() {
System.out.printf("name: %s\n", name);
System.out.printf("id: %s\n", id);
}
public static void main(String[] args) {
var foo = new Foo();
foo.display();
}
}
那么这在java中是一个合法的行为,还是一个非常糟糕的主意?
2条答案
按热度按时间gopyfrb31#
不,这不好。
在对象构造期间调用抽象方法(以及任何类型的可重写方法)是一个坏主意。
这样的调用可能会导致细微的bug,因为对象初始化可能发生在方法调用之前。
pieyvz9o2#
谢谢你的意见。现在我对如何处理这种情况有了一些想法。
1.如果字段可以直接使用默认的ctor构造并稍后配置,我可以在基类中构造它作为最终字段,并在派生构造阶段配置它:
1.如果必须用派生类提供的信息来构造字段,我应该把它放到派生类中,并在基类中添加一个抽象getter:
这是一个合理的设计?