【问题标题】:Overriding an abstract method with a virtual one用虚拟方法覆盖抽象方法
【发布时间】:2014-03-18 10:58:40
【问题描述】:

我正在尝试用子类中的虚拟方法覆盖抽象类中的抽象方法。我(假设直到现在?)理解抽象方法和虚拟方法之间的区别。

显然我做不到,但我的问题是……为什么?根据接受的答案here 和以下场景,我只是没有看到问题:

    public abstract class TopLevelParent
    {
        protected abstract void TheAbstractMethod();
    }

    public class FirstLevelChild1 : TopLevelParent
    {
        protected override void TheAbstractMethod()
        {

        }
    }

    public class FirstLevelChild2 : TopLevelParent
    {
        protected virtual override void TheAbstractMethod()
        {
            //Do some stuff here
        }
    }

    public class SecondLevelChild : FirstLevelChild2
    {
        //Don't need to re-implement the method here... my parent does it the way I need.
    }

所以很明显,我所做的是有一个顶级父级,它有两个继承的子级和另一个继承自其中一个的类。同样,基于我在上面发布的链接中接受的答案:

"一个虚函数,基本上就是说看,这里是功能 这对儿童班来说可能不够好,也可能不够好。所以如果是 足够好,使用这个方法,如果没有,然后覆盖我,并提供 您自己的功能。”

而且二级子级会从父级继承虚方法,从而满足最顶层父级抽象方法的实现要求……有什么问题?

我在某处遗漏了一些细节,阻碍了我对此的理解......

【问题讨论】:

  • 您遇到的具体错误是什么?
  • 标记为覆盖的成员“WindowsFormsApplication.Form1.FirstLevelChild2.TheAbstractMethod()”不能标记为新的或虚拟的

标签: c# inheritance virtual abstract


【解决方案1】:

abstract 方法已经 virtual 一直沿继承链 - 无需在子类中声明 virtual 以允许子类覆盖它 - 子类可以已经覆盖它。

如果您提供实现,则将使用最接近的实现(查看继承列表)。

【讨论】:

    【解决方案2】:

    override 方法隐式虚拟的(在某种意义上它可以在子类中被覆盖),除非标记为 sealed

    观察:

    public class FirstLevelChild1 : TopLevelParent
    {
        protected override void TheAbstractMethod() { }
    }
    
    public class SecondLevelChild1 : FirstLevelChild1
    {
        protected override void TheAbstractMethod() { } // No problem
    }
    
    public class FirstLevelChild2 : TopLevelParent
    {
        protected sealed override void TheAbstractMethod() { }
    }
    
    public class SecondLevelChild : FirstLevelChild2
    {
        protected override void TheAbstractMethod() { } 
        // Error: cannot override inherited member 
        // 'FirstLevelChild2.TheAbstractMethod()' because it is sealed
    }
    

    【讨论】:

    • 啊,是的……我现在明白了。所以在这种情况下,我的虚拟声明本质上是多余的?我能够将其声明为覆盖,并且按预期工作。
    • +1 我不知道我们可以将方法标记为密封 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2013-09-12
    • 1970-01-01
    • 2011-05-21
    • 2012-10-26
    • 1970-01-01
    相关资源
    最近更新 更多