2012-08-05 2 views
5

제 클래스 구조를 살펴보십시오. 나는 가능한 한 상속으로 더 즐겁게하고 싶습니다.C# - 상속 고급

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

이 마지막으로 특정 정책 클래스가 :

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

다음 일반 또 다른 추상 클래스가 존재한다 : 기본 추상 클래스가

첫째. AccidentContainer는 DataContainer에서 상속 :

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

내가 그것을 얻이 여기에 무엇을 사용해야 수정 확실하지 않다 : 컴파일시

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

나는 다음과 같은 오류가 발생합니다. 어쩌면 내가 성취하고자하는 바를 적어야 할 것입니다. 여러 유형의 DataContainer (AccidentContainer, TravelContainer 등)를 PolicyDetailed에서 상속하는 다른 유형의 정책 객체 (예 : PolicyAccident, PolicyTravel 등)가 있습니다. 나는 그들 각각에 대해 "GetActiveAsset"메서드를 호출하고 그들의 특정 타입을 알지 않고 PolicyDetailed를 통해 그들을 참조하려고한다. 동시에 각 클래스가 특정 Datacontainer 하위 클래스를 반환하도록합니다. 그게 가능하니?

+0

특정 컨테이너 유형이 특정 정책 유형을 반환한다고 선언하는 것이 중요합니까? 당신은 반환 된 객체를 PolicyDetailed로 참조하기를 원한다고 말하면 어쨌든 특정한 정보를 잃어버린 것입니다. (AccidentContainer _IS_ a DataContainer를 기억하고, 따라서 서명을 전혀 변경하지 않고 반환 형식 DataContainer가있는 메서드에서 AccidentContainer를 반환 할 수 있습니다. – olagjo

+0

코드의 다른 부분에서 필요합니다. 특정 유형의 정책을 참조하고 해당 부분을 사용해야합니다. 보안 컨테이너. 두 가지 방법을 사용하는 것을 고려해 볼 수 있습니다 - 하나는 DataContainer 객체를 반환하고, 두 번째는 특정 컨테이너를 반환 할 수 있습니다 (하지만 어색함을 느낍니다 :() – 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; 
        }  
    } 
    
  • 당신은 목적을 해소하기위한 새로운 방법 이름 단지을 도입, 상속의 또 다른 수준을 소개 할 수있다. 이것은 아주 못생긴 : 당신은 대신 제네릭이 아닌 PolicyDetailed 클래스에게 인터페이스를 만들고, 새로운 추상 메소드를 선언하고 여전히 인터페이스를 구현하기 위해 명시 적 인터페이스 구현을 사용할 수

    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; 
        }    
    } 
    
  • .