Java OOP设计:类继承类,该类包含继承另一个类的类的字段

Java OOP设计:类继承类,该类包含继承另一个类的类的字段,java,oop,inheritance,Java,Oop,Inheritance,请看以下代码片段: public static class A { public void doA() { } } public static class B extends A { public void doB() { } } public static class AE { protected A field; public AE(A field) { this.field = field; }

请看以下代码片段:

public static class A {

    public void doA() {

    }

}

public static class B extends A {

    public void doB() {

    }

}

public static class AE {
    protected A field;

    public AE(A field) {
        this.field = field;
    }

    public void doStuff() {
        field.doA();
    }

}

public static class BE extends AE {

    // wanna have B field;

    public BE(B field) {
        super(field);
    }

    public void doAnotherStuff() {
        field.doA();
        field.doB(); // error here
    }

}
对于这样的设计问题,最好的解决方案是什么? 我看到两种选择: 1) 每次需要调用doB()时强制转换为B类型字段

2) 将B另存为BE类的另一个字段,并在需要doB()功能时调用此字段:

protected B field2;

    public BE(B field) {
        super(field);
        field2 = field;
    }
这两种解决方案都是显而易见的,并不好。在案例1)中,您失去了运行时强制转换的性能,每次强制转换字段看起来都像是一个错误。 在案例2中)我们在类BE中有两个字段,它们包含指向完全相同的对象B的指针,只是类型不同(类A的字段和类B的字段2); 这个问题有更好的解决方案吗?

您可以使用泛型:

public static class AE<T extends A> {
    protected T field;

    public AE(T field) {
        this.field = field;
    }

    public void doStuff() {
        field.doA();
    }

}

public static class BE extends AE<B> {

    // wanna have B field;

    public BE(B field) {
        super(field);
    }

    public void doAnotherStuff() {
        field.doA();
        field.doB();
    }

}
公共静态类AE{
保护T场;
公共AE(T场){
this.field=字段;
}
公共空间{
field.doA();
}
}
公共静态类可以扩展为AE{
//想要B场;
公共BE(B场){
超级(外地);
}
公共空间不允许使用其他凝灰岩(){
field.doA();
字段doB();
}
}

正如@Eran所建议的,您可以使用泛型,也可以这样做:

public static class AE {
    private A field;

    public AE(A field) {
        this.field = field;
    }
    public void doStuff() {
        field.doA();
    }

    protected A getField() {
        return field;
    }
}

public static class BE extends AE {

    public BE(B field) {
        super(field);
    }

    @Override
    protected B getField() {
        return (B) super.getField();
    }

    public void doAnotherStuff() {
        getField().doA();
        getField().doB(); // no error here
    }

}

添加受保护的getter并在子类中重写它。这样,您只需要强制转换类型一次。

您可以使用泛型这与泛型的答案基本相同,只是您在运行时而不是编译时执行类型检查。何必麻烦呢?谢谢!正是我需要的!现在我觉得自己真的很蠢,我自己都没弄明白。。。
public static class AE {
    private A field;

    public AE(A field) {
        this.field = field;
    }
    public void doStuff() {
        field.doA();
    }

    protected A getField() {
        return field;
    }
}

public static class BE extends AE {

    public BE(B field) {
        super(field);
    }

    @Override
    protected B getField() {
        return (B) super.getField();
    }

    public void doAnotherStuff() {
        getField().doA();
        getField().doB(); // no error here
    }

}