c# - 编译时多态与运行时多态

标签 c# oop

为什么重载在C#中被称为编译时多态和Overriding 运行时多态?

最佳答案

好吧,重载决定(使用哪种方法签名,基于参数1)由编译器做出,而覆盖决定(哪种方法实现 根据方法的目标类型使用)由 CLR 在执行时创建。

不过,我通常不会将重载称为“多态性”。根据我的经验,通常 这个词指的是覆盖。我想重载确实允许您将一种类型的对象视为另一种类型的对象,尽管在那里不需要涉及重载本身——它只是普通的类型转换。

下面是一个示例,显示重载选择是在编译时执行的:

using System;

class Test
{
    static void Foo(object a)
    {
        Console.WriteLine("Object overload called");
    }

    static void Foo(string a)
    {
        Console.WriteLine("String overload called");
    }

    static void Main()
    {
        object x = "hello";
        Foo(x);
    }
}

这里调用了 Foo(object) 重载,因为 x 在编译时是 object 类型——只有在执行时它是已知引用一个字符串。

将其与此示例进行比较:

using System;

class Base
{
    public virtual void Foo()
    {
        Console.WriteLine("Base.Foo called");
    }
}

class Derived : Base
{
    public override void Foo()
    {
        Console.WriteLine("Derived.Foo called");
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();
        x.Foo();
    }
}

这里 compile-time x 的类型是 Base,但是调用的仍然是派生类的覆盖方法,因为 <x 引用的对象的 em>执行时间 类型是 Derived


1 由于方法隐藏等原因,它实际上比这稍微复杂一些 - 但在简单的情况下,您可以将其视为只是选择签名。

关于c# - 编译时多态与运行时多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2152848/

相关文章:

python - 我可以通过 gsl_function 的包装或 cython 重新声明将 cython 类方法分配给 gsl_function 结构吗?

javascript - 在 IE8 中初始化另一个对象内的对象失败

matlab - Matlab 中的静态方法

c++ - 删除数组成员的更好方法是什么?

c# - 从 IWebElement 获取 WebDriver

c# - 回文 - 错误

c# - 哪种方法更好地从数据库中检索数据

c# - 回调的通用存储

java - 面向对象编程中的访问修饰符

c# - GZipping ASP.NET MVC 3 中的内容文件