看一下这段代码:
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类型字段((B) field).doB();
2)将B保存为BE类的另一个字段,并在需要doB()功能时调用此字段:
protected B field2;
public BE(B field) {
super(field);
field2 = field;
}
两种解决方案都很明显,并不好。在情况1)中,您在运行时强制转换中失去了性能,并且每次投射场都看起来像一个错误。 在情况2)中,我们在BE类中有两个字段,它们包含指向完全相同的对象B的指针,仅在类型(类A的字段和类B的字段2)中不同; 对于这个问题有没有更好的解决方案?
答案 0 :(得分: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();
}
}
答案 1 :(得分:0)
正如@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并将其覆盖在子类中。这样你只需要抛出一次类型。