考虑一个简单的AClass
:
class AClass {
private AContent content;
AClass(AContent content) {
this.content = content;
print();
}
protected void print() {
System.out.println("AClass content is "+ content.getValue());
}
}
其中
AContent
由以下定义:class AContent {
int getValue() {
return 1;
}
}
BClass
,扩展AClass
,并由BContent
初始化,该扩展扩展AContent
,如下所示:class BClass extends AClass {
private BContent content;
BClass(BContent content) {
super(content);
this.content = content;
}
@Override
protected void print() {
System.out.println("BClass content is "+ content.getValue());
}
}
其中
BContent
由以下定义:class BContent extends AContent{
@Override
int getValue() {
return 2;
}
}
构造一个
BClass
对象:public static void main(String[] args) {
new BClass(new BContent());
}
产量,可以预期是尝试打印导致的
NullPointerException
System.out.println("BClass content is "+ content.getValue());
在内容初始化之前。
为了克服它,我考虑了两种选择:
从构造函数中删除
print()
调用。这将起作用,但对于我需要的功能不是理想的。b。使
content
为静态并使用静态方法对其进行初始化:private static BContent content;
BClass(BContent content) {
super(init(content));
}
private static BContent init(BContent content) {
BClass.content = content;
return content;
}
这可以工作,但是看起来很丑陋。
我正在寻求有关如何更好地构造此类代码的建议,以使其不仅功能正常,而且符合常规做法。
最佳答案
一种方法是将BContent
传递给AClass
构造函数。这将起作用,因为BContent
是AContent
的子类:
class AClass {
// Make protected so subclasses can access
// (probably better via a protected get method)
protected AContent content;
...
}
class BClass extends AClass {
BClass(BContent content) {
super(content);
}
@Override
protected void print() {
System.out.println("BClass content is "+ content.getValue());
}
}
到
print
方法被调用为content
的时间将被初始化,您将可以。如果您实际上需要在BClass中知道
BContent
的类型,请使用泛型:class AClass<ContentT extends AContent> {
// Make protected so subclasses can access
// (probably better via a protected get method)
protected ContentT content;
...
}
class BClass extends AClass<BContent> {
BClass(BContent content) {
super(content);
}
@Override
protected void print() {
// Now if I wanted I could do things with BContent that aren't
// possible with AContent since the type of BContent is known
System.out.println("BClass content is "+ content.getValue());
}
}