正在初始化子 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,并由扩展 AContentBContent 初始化,如下所示:

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 构造函数。这会起作用,因为 BContentAContent 的子类:

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