初始化子类字段

时间:2017-02-18 07:12:59

标签: java initialization field subclass extending

考虑一个简单的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());

在内容初始化之前。
为了克服它,我想到了两个选择:
a。从构造函数中删除print()调用。这可行,但不适合我需要的功能 b。使用content static并使用静态方法对其进行初始化:

private static BContent content;

BClass(BContent content) {

  super(init(content));
}

private static BContent init(BContent content) {

    BClass.content = content;
    return content;
}

这会起作用,但看起来很安静丑陋。
我正在寻求有关如何更好地构建此类代码的建议,使其不仅具有功能性,而且符合常规做法。

2 个答案:

答案 0 :(得分:2)

一种方法是将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());
    }
}

答案 1 :(得分:0)

根据@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;
    }
}
相关问题