如果派生类没有覆盖该方法,应该调用哪个版本?

Zoo*_*mIn 6 c# polymorphism overriding

我正在尝试理解C#中覆盖和虚拟的需要,所以我编写了以下代码:

using System;
namespace Override
{
    class Base 
    {
        public virtual void method() 
        {
            Console.WriteLine("Base method");
        }
    }
    class Derived : Base 
    {
        public override void method()
        {
            Console.WriteLine("Derived method");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Derived d = new Derived();
            d.method();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我期待调用和打印"派生方法".然后我编写了以下代码而不使用虚拟/覆盖组合.

using System;
namespace Override
{
    class Base 
    {
        public void method() 
        {
            Console.WriteLine("Base method");
        }
    }
    class Derived : Base 
    {
        public void method()
        {
            Console.WriteLine("Derived method");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Derived d = new Derived();
            d.method();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到了相同的结果,即"派生方法"被调用和打印.我的问题是,如果代码在没有虚拟/覆盖的情况下工作,我预期,他们需要什么?或者我在这里遗失了什么?

Irf*_*fan 12

在源代码中,您总是在进行简单继承而没有任何多态行为.始终创建派生类的实例并将其分配给派生类实例变量.

DerivedClass d = new DerivedClass(); // here no polymorphism, and only inheritance is there
Run Code Online (Sandbox Code Playgroud)

因此,当您使用类变量调用方法时,无论该方法在父类中是否为虚方法,它都将始终调用DerivedClass方法.

在多态性中,您的程序不知道您调用该方法的类的确切类型(此概念称为后期绑定).如下例所示:

BaseClass b = new DerivedClass(); // here b is a base class instance but initiated using derived class
Run Code Online (Sandbox Code Playgroud)

在调用b.method()之后,它将执行后期绑定并将显示多态行为(仅当该方法已在基类中设置为virtual时)

注意:virtual关键字将绑定到正确的方法版本延迟到运行时,并且是实现多态的核心关键.因此,对于精确的多态行为,在父类中将方法声明为虚拟,然后在子类中,将该方法设置为ovverride.


Cho*_*ett 8

virtual允许在运行时根据编译时不可用的信息选择正确的方法版本.考虑以下对您的示例的调整:

using System;
namespace Override
{
    class Base 
    {
        public virtual void method() 
        {
            Console.WriteLine("Base method");
        }
    }
    class Derived : Base 
    {
        public override void method()
        {
            Console.WriteLine("Derived method");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Derived d = new Derived();
            Base b = d;
            b.method();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用virtual/ override,此代码将显示Derived method,因为在运行时我们可以看到它b实际上是一个Derived实例.如果没有virtual/ override,它会显示Base method,作为申报类型b为Base.