【问题标题】:C# PolymorphismC# 多态性
【发布时间】:2010-10-01 18:36:20
【问题描述】:


运行时多态性和编译时多态性有什么区别?另外,早期绑定和后期绑定有什么区别?示例将不胜感激。

【问题讨论】:

  • 您希望更好地搜索示例?
  • 是否应该将其标记为homework
  • @keyboardP:不,虽然他可能会问你可能在谷歌上找到的问题,但这些问题的目的是为了学习,而不是“为我做作业”。
  • @keyboardp:看起来仍然以学习为导向。他可能要求提供示例,但有些人从代码中学习得更快,因为没有关于他可能需要编写什么代码的详细信息我认为这里的任何示例都不会“给”他答案,这将指导他正确的方向。如果您不想帮助教学,那很好,但不要妨碍尝试学习的人,尤其是当他不想要“只是答案”时。

标签: c# polymorphism


【解决方案1】:

编译时多态性

方法重载就是一个很好的例子。您可以有两个具有相同名称但具有不同签名的方法。编译器会在编译时选择正确的版本。

运行时多态性

在子类中覆盖父类的虚方法就是一个很好的例子。另一个是从接口实现方法的类。这允许您在使用子指定的实现时在代码中使用更通用的类型。给定以下类定义:

public class Parent
{
    public virtual void SayHello() { Console.WriteLine("Hello World!"); }
}

public class Child : Parent
{
    public override void SayHello() { Console.WriteLine("Goodbye World!"); }
}

以下代码将输出“再见世界!”:

Parent instance = new Child();
instance.SayHello();

早期绑定

在编译时指定类型:

SqlConnection conn = new SqlConnection();

后期装订

类型在运行时确定:

object conn = Activator.CreateInstance("System.Data.SqlClient.SqlConnection");

【讨论】:

  • .Net 泛型如何适合这里的图片?在 C++ 中,模板表示编译时多态性。谢谢
【解决方案2】:

更新:请参阅 Eric Lippert 对此答案的 cmets。

在 C#2 中,所有绑定都是早期的,因为 C#2 是一种静态类型语言。后期绑定语言是一种方法绑定发生在运行时的语言。 (C#4 包含一个后期绑定功能,并引入了dynamic。)

我不确定您所说的运行时多态性与编译时多态性是什么意思。

C# 编译器将在编译时确定将调用哪个方法重载。实例的运行时类型将确定将执行特定方法重载的哪个实现。这仍然被认为是早期绑定,即使它发生在运行时,因为所选方法被限制为特定虚拟方法重载的实现,并且这样的调用不可能生成与类型相关的异常,例如 can使用动态语言和后期绑定发生。

【讨论】:

  • C# 2 支持语言级别的后期绑定,以 virtual dispatch 的形式。在虚拟调度语言中,方法调用是后期绑定,因为调用的确切方法直到运行时才确定。方法的签名是在编译时确定的,但实际调用的方法不是。 C# 4 支持动态后期绑定:它可以在运行时确定关于方法的所有内容(除了它的名称)。
  • 回复:您的更新:意见不一。有些人认为虚拟调度是后期绑定,因为调用的方法是在运行时确定的。 (这些人往往是具有 C 或其他一些主要是静态绑定语言背景的人。)有些人认为它是早期绑定,因为包含方法指针的 slot 是在编译时确定的。 (这些人往往习惯于 COM 编程或 C++,几乎每个调用都是虚拟的。)我个人尝试只使用“后期绑定”来表示“动态”。
  • @Eric Lippert - 好的,这是有道理的。您对“后期绑定”的使用似乎与我的相似。我一直认为“早”和“晚”实际上是指当出现问题时检测到错误的时间。感谢您的 cmets!
  • 这是区分的好方法。对于模糊的术语“绑定”甚至意味着什么,存在很多混淆。我同意您的建议:“绑定”操作是执行确定类型信息并产生错误或唯一最佳类型分配的分析。 (在“类型信息”中,我包括类型的成员,例如重载方法。)
【解决方案3】:

关于编译时和运行时多态性之间差异的非常简单直接的答案。

编译时多态 - 方法重载(具有相同的方法名称但具有不同的签名)。请在此 URL 上查看有关方法重载的视频 http://csharp-video-tutorials.blogspot.com/2012/06/part-25-c-tutorial-method-overloading.html

运行时多态 - 方法覆盖(在运行时调用子类覆盖的方法,使用基类引用变量称为运行时多态)。请在此 URL 上查看有关方法覆盖(多态性)的视频 http://csharp-video-tutorials.blogspot.com/2012/06/part-23-c-tutorial-polymorphism.html

【讨论】:

    【解决方案4】:

    早期绑定和静态绑定是一样的。后期绑定和动态绑定是一样的。动态绑定意味着编译器将选择在运行时调用哪个方法。静态绑定意味着编译器将选择在编译时调用的方法。当我们使用is-继承关系并将派生类引用分配给基类引用。我们将只允许调用或访问基类引用。roslyn 服务将提供关键字 virtual、abstract 和 override 以通过基类引用调用派生类成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-25
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多