正在初始化子 class 字段
Initializing sub class fields
考虑一个简单的 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
,并由扩展 AContent
的 BContent
初始化,如下所示:
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());
在内容初始化之前。
为了克服它,我想到了两个选择:
a.Remove print()
来自构造函数的调用。这会起作用,但不符合我需要的功能。
b.Make 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());
}
}
根据@Oliver Dain 的回答,我得到了:
class AClass <T extends AContent>{
private T content;
AClass(T content) {
this.content = content;
print();
}
protected void print() {
System.out.println("Content is "+ getContent().getValue());
}
public T getContent() {
return content;
}
}
class BClass extends AClass<AContent> {
BClass(BContent content) {
super(content);
}
public static void main(String[] args) {
new BClass(new BContent());
}
}
class AContent {
int getValue() {
return 1;
}
}
class BContent extends AContent{
@Override
int getValue() {
return 2;
}
}
考虑一个简单的 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
,并由扩展 AContent
的 BContent
初始化,如下所示:
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());
在内容初始化之前。
为了克服它,我想到了两个选择:
a.Remove print()
来自构造函数的调用。这会起作用,但不符合我需要的功能。
b.Make 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());
}
}
根据@Oliver Dain 的回答,我得到了:
class AClass <T extends AContent>{
private T content;
AClass(T content) {
this.content = content;
print();
}
protected void print() {
System.out.println("Content is "+ getContent().getValue());
}
public T getContent() {
return content;
}
}
class BClass extends AClass<AContent> {
BClass(BContent content) {
super(content);
}
public static void main(String[] args) {
new BClass(new BContent());
}
}
class AContent {
int getValue() {
return 1;
}
}
class BContent extends AContent{
@Override
int getValue() {
return 2;
}
}