如果一个虚方法被声明为抽象的

6

我的朋友问我一个抽象方法是否可以有虚拟修饰符。 我回答说,不可以。 因为抽象方法隐式地也是虚方法,它不能具有虚拟修饰符。

但是在阅读 MSDN文章之一时,我看到了这个:

... 如果一个虚方法被声明为抽象,则对于从抽象类继承的任何类而言,它仍然是虚拟的。 继承抽象方法的类无法访问该方法的原始实现 - 在先前的示例中,F类上的DoWork无法调用D类上的DoWork。通过这种方式,抽象类可以强制派生类为虚方法提供新的方法实现....

我无法正确理解第一句话。 请问他们想表达什么意思?

谢谢。


1
第一句话的意思是,abstract 关键字在“虚拟性”方面没有任何改变,也就是说方法仍然是 virtual 的,因此仍然会表现出多态性。 - BartoszKP
@BartoszKP 在阅读了Heinzi的回答和你的评论后,我明白了。谢谢。 - Farhad Jabiyev
2
这可能会引起您的兴趣:http://ericlippert.com/2011/02/07/strange-but-legal/ - Eric Lippert
@EricLippert 感谢您提供的链接。它非常有意义,也很有趣。 - Farhad Jabiyev
2个回答

7
当你直接查看引用段落上面的代码示例时,问题就变得更加清晰:
public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

虚方法D.DoWorkE继承,并在此处声明为抽象。该方法仍然是虚方法,只不过也成为了抽象方法。
正如您所说,抽象方法总是虚方法。如果您的朋友仍然不信,请看这个官方引用

抽象方法隐式地是虚方法。


2
这个方法仍然是虚拟的,只不过也变成了抽象的。这句话已经足够让我理解了。非常感谢。 - Farhad Jabiyev
1
C#关键字abstract(应用于方法)在VB.NET中被命名为MustOverride。我一直认为这是一个笨拙的名称,但实际上它非常适合在这里展示的非常特定的情况(在派生类中将virtual方法再次变为abstract)。 - stakx - no longer contributing
@stakx:确实。virtual 被命名为 Overridable,因此 MustOverride 暗示着 Overridable 是完全合理的。 - Heinzi

1
抽象类可以使用“abstract”关键字重写“virtual”成员:
public class B
{
    public virtual void M() { }
}
public abstract class D : B
{
    public abstract override void M();
}
public abstract class D2 : D
{
    public override void M() { }
}

该句话表示D2必须覆盖D中声明为抽象的void M()。如果它声明为D2 : B,这是可选的,但现在D2必须遵守D中指定的合同,同时M()也将像覆盖“普通”虚成员一样行事,因为M()既是虚的又是抽象的。请保留html标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接