关于c#:从derived而不是base调用的虚方法

Virtual method called from derived instead of base

有人能给我解释一下,当我将类强制转换为基方法时,为什么要调用被重写的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Base virtual method");
        }
    }

    sealed class Derived : Base
    {
        public override void VirtualMethod()
        {
            Console.WriteLine("Overriden method");
        }
    }

    static void Main(String[] args)
    {
        Derived d = new Derived();
        ((Base)d).VirtualMethod();
    }

我的意思是这个代码打印:

1
Overriden method

而不是

1
Base virtual method

它是运行时还是编译时的未来?

我知道我可以通过调用base.VirtualMethod()从派生的调用基的虚方法,但是我可以从外部调用它吗?(就像来自Main或其他阶级)


方法实现是根据对象的执行时间类型选择的。这是重点的很大一部分。任何人都可以使用:

1
2
3
4
public void Foo(Base b)
{
    b.VirtualMethod();
}

…而且不需要知道或关心什么是执行类型,因为多态性将处理它。

I know i can call the Base's virtual method from the derived by calling base.VirtualMethod() but can I call it from outside?

不(至少,没有一些可怕的黑客非虚拟地调用虚拟方法),这是封装的一部分。重写的实现有效地替换了该对象的原始实现。


如果要访问基本实现,则不应使用override,而应使用new。override重写任何父实现,new"隐藏"父实现,以便您可以通过将其强制转换为父对象,然后调用该方法来访问实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
internal class Program
{
    private static void Main(string[] args)
    {
        Derived d = new Derived();
        d.VirtualMethod();
        ((Base) d).VirtualMethod();

        Console.ReadLine();
    }

    private class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Base virtual method");
        }
    }

    private sealed class Derived : Base
    {
        public new void VirtualMethod()
        {
            Console.WriteLine("Overriden method");
        }
    }
}

这将输出:

Overriden method
Base virtual method