【问题标题】:C# - advanced inheritanceC# - 高级继承
【发布时间】:2012-08-02 22:07:45
【问题描述】:

请看一下我的班级结构。我想我希望在继承方面获得更多乐趣。

首先有一个基础抽象类:

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 等)。我想在不知道它们的具体类型并通过 PolicyDetailed 引用它们的情况下对它们中的每一个调用“GetActiveAsset”方法。同时我希望每个类都返回它们特定的 Datacontainer 子类。这可能吗?

【问题讨论】:

  • 声明特定容器类型返回其特定策略类型对您来说真的很重要吗?您说您想将返回的对象引用为 PolicyDetailed,这样您无论如何都会丢失特定信息! (请记住,AccidentContainer IS 是一个 DataContainer,因此 AccidentContainer 可以从返回类型为 DataContainer 的方法返回,而无需更改任何签名)
  • 我在代码的其他部分需要它,我在其中引用特定类型的策略并使用其特定容器。我可能会考虑使用两种方法——一种会返回一个 DataContainer 对象,第二种可能会返回一个特定的容器(但感觉有点笨拙:()

标签: c# inheritance polymorphism


【解决方案1】:

问题是您不能在声明具有相同签名的任何其他方法时覆盖同一类中的非泛型方法。

有几个选项:

  • 到目前为止,最简单的方法是给这两种方法起不同的名称。然后你可以在PolicyDetailed&lt;T&gt; 中给出一个实现,它只是委托给新​​的抽象方法:

    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 类改为接口,并使用显式接口实现来声明新的抽象方法并仍然实现该接口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多