抽象类与抽象字段和子类化没有铸造
问题描述:
我创建了一个抽象基类。它包含应该由任何子类扩展的对象:抽象类与抽象字段和子类化没有铸造
public abstract class AbstractParent {
protected AbstractObject subMePlz;
// ... some fields that all subclasses need
public AbstractParent() {
this.subMePlz = createThisInYourExtendedClass();
}
public abstract AbstractObject createThisInYourExtendedClass();
}
的abstractObject:
public abstract class AbstractObject {
// ... some fields/methods that all subclasses need
}
我要的是能够使用扩展字段中扩展类无铸造:
public class ExtendParent extends AbstractParent {
// .. some unique fields
public ExtendParent(){
super();
}
public ConcreteObject createThisInYourExtendedClass(){
return new ConcreteObject();
}
// what I want to do - no cast
public void doSomethingWithSubMePlzWithoutCastingIt() {
System.out.println(this.subMePlz);
}
// what I end up doing - gotta cast
public void doSomethingWithSubMePlzWithoutCastingIt() {
System.out.println((ConcreteObject)this.subMePlz);
}
}
需要一个比较器改变我应该如何实现这个? - 我正在考虑一个通用的比较器,用于其子类可以使用的AbstractObjects列表。
答
这听起来像你需要使它通用:
public abstract class AbstractParent<T extends AbstractObject> {
protected T subMePlz;
// ... some fields that all subclasses need
public AbstractParent() {
this.subMePlz = createThisInYourExtendedClass();
}
public abstract T createThisInYourExtendedClass();
}
public class ExtendParent extends AbstractParent<ConcreteObject> {
...
}
注意,调用构造函数内的非私有方法是通常一个坏主意 - 子类不会被完全初始化还,这可能会使你很难推断你能够真正依赖多少。
答
你有两个选择:
- 放弃该项目申报的超领域。相反,将内部抽象“getter”方法添加到您的超类中 - 基本上,
AbstractParent
应该有一个方法abstract AbstractObject getSubMePlz()
。 - 在您的子类中使用泛型来设置
subMePlz
的类型:defineAbstractParent<T>
对其subMePlz
字段具有T
。
就个人而言,我经常发现选项1是非常愉快扩展性 - 例如,你可以有其他子类,缩小,但仍未宣布它的getSubMePlz()
返回类型,它可以是有利的。
答
为什么不利用这一点 -
super.subMePlz
代替本 -
(ConcreteObject)this.subMePlz
这样,你将不再需要转换。
答
您可以保存子类中的对象的副本,但具有正确的类。
public class ExtendParent extends AbstractParent {
ConcreteObject concreteObject;
public AbstractObject createThisInYourExtendedClass(){
ConcreteObject concreteObject = new ConcreteObject();
return concreteObject;
}
public void doSomethingWithSubMePlzWithoutCastingIt() {
System.out.println(concreteObject);
}
...
对于选项1会是抽象的T getSubMePlz()? – gebuh 2012-04-24 17:54:41
选项1根本不涉及任何泛型,但我想你可以将两者结合起来。 – 2012-04-24 18:00:15