【问题标题】:Compile time polymorphism / Overloading编译时多态/重载
【发布时间】:2011-03-30 20:27:02
【问题描述】:

为什么重载被认为是多态的一种形式,或者是实现多态的一种方式。

对我来说,多态意味着多种形式,我不太明白重载如何帮助实现这一点。

【问题讨论】:

  • 重载不被认为是一种多态性。
  • @David Heffernan - 重载有时被称为“临时多态性”:en.wikipedia.org/wiki/…
  • @Lee 好吧,如果你愿意,你可以调用重载多态。我不会。
  • 是的,我从不知道方法重载是多态性,直到我阅读了您引用的 wiki。我认为该条目需要一个星号,否则几乎没有实际开发人员会以这种方式使用该术语
  • 我最近一直在做一些采访,很多受访者回答超载作为“什么是多态性”的答案。听到这个答案,我惊呆了,开始怀疑自己。但我仍然不认为它是一种多态性......

标签: c# .net polymorphism


【解决方案1】:

多态是发生在运行时的事情。就 OOP 而言,它是调用方法的实践,并且在编译时,知道该方法将在哪个对象上调用。典型的例子是 Shapes、Circles、Square 等。你有一个 Shapes 的集合,每一个都被实例化为一个 Circle、Square 等等。编译器既不知道也不关心您在任何给定时间调用DrawErase 的Shape 类型;该决定发生在程序运行时。

方法重载发生在编译时。您有多个具有相同名称参数不同的方法。当您调用其中一种方法时,编译器将根据您提供的参数决定哪个重载最匹配。

为什么重载被认为是多态性的一种形式,或者是实现多态性的一种方式。

从根本上说,多态性是在同一个 API 下处理多种类型的能力。所以从技术上讲,方法重载确实属于这一点。事实上,根据wikipedia 的说法,方法重载被称为“临时多态性”,但我从未听说过这个术语在现实生活中使用过(并不是说我是最终权威)。 通常多态性专门指方法的动态绑定,如 Shape、Circle、Square 示例。

还有“参数多态性”,但根据我可能有限的经验,这通常被称为泛型或模板,具体取决于语言(它们相同;存在细微差别两者之间)

【讨论】:

  • 多态性不需要在运行时发生。考虑运算符重载——这不是编译时多态的一种形式吗?如果这个答案明确包括正在讨论的“子类型多态性”,我会+1:无聊的单调度运行时绑定:-)
  • 你是对的。我确实提到了 method 重载,它在技术上被称为 ad-hoc 多态性;运算符重载只是它的扩展。而且我不知道“子类型多态性”是另一个的正确名称。对您的评论 +1 :)
【解决方案2】:

为什么重载被认为是一种多态性

事实并非如此。这是不正确的信息。重载不是多态性。来自Wikipedia's Polymorphism in object-oriented programming页面:

方法重载和方法覆盖本身都不是多态性的实现。

【讨论】:

    【解决方案3】:

    方法重载可能是动态语言或使用多重分派解决方法重载的语言中的一种多态性形式,但在 C# 中不存在。 C# 的方法重载没有多态性,因为每个调用的重载都是在编译时严格选择的(dynamic 变量除外)。

    更新

    @Lee 声明“没有要求多态性是运行时机制。”

    是的,有。

    在 C# 中,方法重载是一种方便的方式来传达意图,并通过为多个方法提供相同的名称来避免令人讨厌的方法名称。但是假设 C# 没有方法重载。假设一个方法的 signature 完全由它的名字组成,忽略参数类型。这种假设的语言会丢失什么?

    嗯,在这种语言中,我们必须给每个方法一个不同的名称。我们将不得不创建 WriteLineString、WriteLineInt32、WriteLineUInt32 等。从可用性的角度来看,这将是非常糟糕的。

    但是语言的表达能力会发生什么变化?没有。我们仍然可以编写相同的代码,只需更改方法名称。编译器会将相同的调用解析到相同的位置。 IL 将完全相同。效率、功率或复杂性没有区别。

    因此,如果语言的表达能力和编译的代码在 C# 和 no-overloads-C# 中是相同的,那么重载怎么可能被认为是“多态性”?多态性意味着根据对象的类型表现出不同的行为。如果去除重载并不能改变对象的行为,那么重载怎么会涉及到多态性呢?

    运行时编译时行为是多态性的核心,与方法重载无关。

    【讨论】:

    • 你能给我一些这些语言的例子吗?
    • @pdiddy - 我不确定,但也许 Ruby 是这样的? (我还以为你现在用的是脏钱之类的名字?)
    • 没有要求多态性是一种运行时机制。
    • @jeffrey:哈哈,是的,这是我的新组名,但当我单飞时,它是 PDiddy homie!
    • @Jeffrey - 您的编辑并没有改变重载是一种多态性这一事实,但即使忽略这一点,也存在可以在编译时解决的参数多态性(例如 c++ 模板)。
    【解决方案4】:

    这是有争议的,但有些人认为它是一种表单,因为它允许您在使用相同名称的同时处理多个表单。如:

    public static class Math
    {
        int Min(int x, int y) { ... }
    
        double Min(double x, double y) { ... }
    }
    

    通过这种方式,您可以调用 Math.Min,它会根据传递给它的参数类型选择正确的方法(是的,您也可以使用泛型来做到这一点,但这只是作为重载的简单说明)。

    【讨论】:

      【解决方案5】:

      当您需要采用不同类型参数的同一方法的不同版本时,您可以使用方法重载。重载是一个面向对象的编程概念,多态也是。重载不等于对象多态。

      通过对象多态性,您可以为提供相同方法和签名的实现的对象定义不同的行为。

      【讨论】:

        猜你喜欢
        • 2012-01-11
        • 1970-01-01
        • 1970-01-01
        • 2020-05-21
        • 1970-01-01
        • 2011-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多