2012-08-05 100 views
5

請看看我的班級結構。我想我想繼承更多的樂趣。C# - 高級繼承

首先出現的是一個抽象基類:

public abstract class PolicyDetailed 
{ 
    internal abstract DataContainer GetActiveAsset(); 
} 

接下來還有另外一個抽象類,這是通用的:

public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer 
{ 
    internal new abstract T GetActiveAsset(); 
} 

最後,還有一個具體的策略類。 AccidentContainer從DataContainer繼承:

public class PolicyAccident : PolicyDetailed<AccidentContainer> 
{ 
    internal override AccidentContainer GetActiveAsset() 
    { 
     return null; 
    } 
} 

在編譯過程中,我得到了以下錯誤:

'PolicyAccident' does not implement inherited abstract member 'PolicyDetailed.GetActiveAsset()' 

我不知道我應該用什麼修飾這裏得到它的工作。也許我也應該寫下我想達到的目標:我有一組不同類型的策略對象(例如PolicyAccident,PolicyTravel等),它們從PolicyDetailed繼承了不同類型的DataContainer(AccidentContainer,TravelContainer等)。我想在他們每個人身上調用「GetActiveAsset」方法,但不知道他們的具體類型,並通過PolicyDetailed引用它們。同時,我希望每個類都返回他們特定的Datacontainer子類。那可能嗎?

+0

對於您聲明特定容器類型是否返回其特定策略類型是否真的很重要?你說你想引用返回的對象作爲PolicyDetailed,這樣你就失去了具體的信息! (請記住,AccidentContainer _IS_ DataContainer和AccidentContainer因此可以從返回類型爲DataContainer的方法返回,而根本不會更改任何簽名) – olagjo 2012-08-05 22:02:47

+0

我在代碼的其他部分需要它,我在其中引用特定類型的策略並使用它容器。我可能會考慮使用兩種方法 - 一種會返回一個DataContainer對象,其次可能會返回一個特定的容器(但它感覺很笨拙) – Rummy 2012-08-06 12:51:17

回答

6

問題是,您不能重寫相同類中的非泛型方法,因爲您聲明具有相同簽名的任何其他方法。

有幾個選項:

  • 到目前爲止,最簡單的就是給這兩種方法不同的名字。然後你就可以在PolicyDetailed<T>這只是代表新的抽象方法得到實現:

    public abstract class PolicyDetailed 
    { 
        internal abstract DataContainer GetActiveAsset(); 
    } 
    
    public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer 
    { 
        internal abstract T GetActiveAssetGeneric(); 
    
        internal override DataContainer GetActiveAsset() 
        { 
         return GetActiveAssetGeneric(); 
        } 
    } 
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer> 
    { 
        internal override AccidentContainer GetActiveAssetGeneric() 
        { 
         return null; 
        }  
    } 
    
  • 可以介紹繼承的另一個層面,用於橋接目的引入一個新的方法名稱只是。這是很醜陋:

    public class DataContainer {} 
    public class AccidentContainer : DataContainer{} 
    
    public abstract class PolicyDetailed 
    { 
        internal abstract DataContainer GetActiveAsset(); 
    } 
    
    // This only exists to satisfy the base class abstract member, 
    // but at the same time allowing PolicyDetailed<T> to introduce 
    // a new member with the same name. 
    public abstract class PolicyDetailedBridge<T> : PolicyDetailed 
        where T : DataContainer 
    { 
        protected abstract T GetActiveAssetGeneric(); 
    
        internal override DataContainer GetActiveAsset() 
        { 
         return GetActiveAssetGeneric(); 
        } 
    } 
    
    public abstract class PolicyDetailed<T> : PolicyDetailedBridge<T> 
        where T : DataContainer 
    { 
        protected sealed override T GetActiveAssetGeneric() 
        { 
         // Call the *new* abstract method. Eek! 
         return GetActiveAsset(); 
        } 
    
        internal abstract new T GetActiveAsset(); 
    } 
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer> 
    { 
        internal override AccidentContainer GetActiveAsset() 
        { 
         return null; 
        }    
    } 
    
  • 你可以使非通用PolicyDetailed類的接口來代替,並用顯式接口實現聲明一個新的抽象方法,並且仍然實現接口。