2012-04-24 145 views
0

我創建了一個抽象基類。它包含應該由任何子類擴展的對象:抽象類與抽象字段和子類化沒有鑄造

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列表。

回答

4

這聽起來像你需要使它通用:

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> { 
    ... 
} 

注意,調用構造函數內的非私有方法是通常一個壞主意 - 子類不會被完全初始化還,這可能會使你很難推斷你能夠真正依賴多少。

3

你有兩個選擇:

  1. 放棄該項目申報的超領域。相反,將內部抽象「getter」方法添加到您的超類中 - 基本上,AbstractParent應該有一個方法abstract AbstractObject getSubMePlz()
  2. 在您的子類中使用泛型來設置subMePlz的類型:define AbstractParent<T>對其subMePlz字段具有T

就個人而言,我經常發現選項1是非常愉快擴展性 - 例如,你可以有其他子類,縮小,但仍未宣佈它的getSubMePlz()返回類型,它可以是有利的。

+0

對於選項1會是抽象的T getSubMePlz()? – gebuh 2012-04-24 17:54:41

+0

選項1根本不涉及任何泛型,但我想你可以將兩者結合起來。 – 2012-04-24 18:00:15

0

爲什麼不利用這一點 -

 super.subMePlz 

代替本 -

(ConcreteObject)this.subMePlz 

這樣,你將不再需要轉換。

0

您可以保存子類中的對象的副本,但具有正確的類。

public class ExtendParent extends AbstractParent { 
    ConcreteObject concreteObject; 

    public AbstractObject createThisInYourExtendedClass(){ 
    ConcreteObject concreteObject = new ConcreteObject(); 
    return concreteObject; 
    } 
    public void doSomethingWithSubMePlzWithoutCastingIt() { 
    System.out.println(concreteObject); 
    } 

    ...