2012-08-05 10 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は、データコンテナから継承:

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

コンパイル中に、私は次のエラーを取得する:

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

私はそれを動作させるために、ここで使用する必要がありますどのような修飾子を確認していません。おそらく私は達成したいことも書いておくべきです:異なるタイプのDataContainer(AccidentContainer、TravelContainerなど)でPolicyDetailedを継承する異なるタイプのポリシーオブジェクト(PolicyAccident、PolicyTravelなど)のコレクションがあります。私は "GetActiveAsset"メソッドを呼び出すときに、それぞれの型を知らずにPolicyDetailedを使って参照する必要があります。同時に、それぞれのクラスが特定のDatacontainerサブクラスを返すようにしたいと思います。それは可能ですか?

+0

特定のコンテナタイプが特定のポリシータイプを返すことを宣言することは本当に重要ですか?あなたは、返されたオブジェクトをPolicyDetailedとして参照したいと思っていて、とにかく特定の情報を失うことになります。 (AccidentContainer _IS_ a DataContainerを覚えているので、戻り値の型のDataContainerを持つメソッドからAccidentContainerを返すことができます) – olagjo

+0

コードの他の部分で必要なのは、特定の種類のポリシーを参照し、安全な容器。私は2つのメソッドの使用を検討するかもしれません - 1つはDataContainerオブジェクトを返し、2つ目は特定のコンテナを返すことができます(しかし、それは不器用な感じです:() – Rummy

答えて

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クラスのインタフェースを行い、新しい抽象メソッドを宣言し、まだインターフェイスを実装するために、明示的なインターフェイスの実装を使用することができます。