【问题标题】:What is the difference between polymorphism and overloading?多态性和重载有什么区别?
【发布时间】:2016-09-30 04:31:32
【问题描述】:

我理解多态性并且对重载有模糊的理解,但如果有人彻底理解这两个概念来解释分类差异是什么以及重载是否是多态性的一种形式(似乎对此存在分歧),我将不胜感激。

【问题讨论】:

  • 你可能比在维基百科上查找更糟糕:en.wikipedia.org/wiki/Polymorphism_%28computer_science%29
  • Haskell 具有 参数多态性,您可以在其中拥有在多种类型上相同工作的函数,例如length :: [a] -> Int 适用于字符串列表、双精度列表等。您只需要一个定义,因为参数多态值不关心参数是什么,只关心它的使用位置。它还具有用于 ad hoc polymorphism 的类型类,实现依赖于类型的函数,例如show :: Show a => a -> String 是一系列函数,每个函数都有自己的定义:show :: Int -> String, show :: Double -> String, ...

标签: c++ haskell computer-science


【解决方案1】:

重载是多态性的一个子集。多态性有两种类型:运行时和编译时。重载属于后一种(还有一些其他方面的编译时/静态多态性以及模板函数指针

通常作者将多态性称为在运行时完成的(除非指定),如果您在谈论多态性,那么显然 是在运行时完成的运行时(John 的回答已经在 inheritance/virtual function 在他的回答中提出了基本的区别)并且当你的函数参数确定要调用哪个重载时,重载是在编译时完成的.

重载 - 静态多态 (演示)

下面的截图可以演示函数重载是如何静态的(在运行时解决

附言

如果你想看看,这是一个关于overloading and virtual functions的相关问题

【讨论】:

  • C++ 也有“静态多态性”,它不会重载。
  • @JohnZwinck 我的意思是它的一种静态多态性。但感谢您引起注意。我已经更新了
  • 我不认为所有的函数重载都是一种动态多态。编译器必须在编译时解决非虚函数重载。
  • @TrevorHickey 我认为你误读了我的评论。我的意思是重载是不同类型的 static 多态性之一(模板,函数指针是其他类型的)我添加了屏幕截图以进一步阐述它
【解决方案2】:

多态性的核心是多个事物,它们都具有一组一致的行为,因此您可以在特定算法或流程中将一个事物替换为另一个事物。只要它们都提供预期的接口,该过程仍然有效。

重载并没有这样的基础。它只是用相同名称命名两个或多个函数的能力,只要它们具有不同的参数列表。编译器会根据您传递的参数类型来确定您实际指的是哪个函数。

现在可以使用重载来创建多态性。考虑以下几点:

template<typename T>
void func(T t) {call(t);}

这将调用call,将t 作为参数传递。只要您提供 T 类型,其中 call(t) 是合法的 C++ 代码,这将起作用。您可以通过重载函数 call 来实现这一点,以将您感兴趣的任何类型与 func 一起使用:

void call(int);
void call(float);
void call(vector<int>);

这样,func 是一个相对于其参数是多态(静态)的函数。它可以对任何类型执行其操作,只要该类型具有适当的接口即可。该接口能够使用该类型的变量调用函数call

func(5); //Legal
func(13.4); //Legal
func(vector<int>{4, 3, 2, 1}); //Legal
func(vector<float>{}); //NOT legal

这里,我们使用call的函数重载,通过func函数创建一种多态形式。但这并不意味着重载就是多态。

重载是一种语言工具。多态是一个概念。多态性是关于使多个对象都以相同的方式工作。重载只是为不同的函数赋予相同名称的一种方式。

【讨论】:

    【解决方案3】:

    多态性:一种方法具有多种实现,具体取决于调用它的参数的类型。在编译时通常不知道。参数的数量是固定的,在 C++ 中唯一重要的参数是第一个参数 (this)。在 C++ 中,通用版本需要一个带有 virtual 方法的基类。

    重载:一个名称实际上是多个方法,具体取决于调用它的参数的数量和类型。总是在编译时决定。不涉及基类。

    如果您想打个比方:多态性是指您聘请十几位专业机械师来处理汽车,每个人都具有do_work(vehicle)take_vacation(duration) 之类的功能。每个人都做了不同的事情,但除了 C++ 中的“隐式 this”参数(在 Python 中也称为 self 等)之外,它们都具有相同的签名。重载是指你雇佣通才技师,每个人都有do_work(steering)do_work(lighting)do_work(engine) 等。

    【讨论】:

    • 最后一段是金!!
    • “编译时多态性”怎么样?
    • @NickyC:C++ 中有两种编译时多态性:一种是优化,因为编译器会看到需要调用哪个实现,另一种是使用模板的语言特性元编程。第一个仍然依赖virtual 方法但提高了性能;第二个依赖于显式使用类型进行编程。
    • 实际上,我的意思是,“编译时多态性”一词的存在可能是您答案的反例。您对 polymorphism 的描述似乎更多地是关于 dynamic dispatch,而不是具有更广泛含义的术语“polymorphism”。
    • @NickyC:当然,这就是为什么我在回答中表示“在编译时通常不知道”。但是 OP 是新手,所以这个讨论对于给定的问题基本上是题外话。
    猜你喜欢
    • 1970-01-01
    • 2010-09-12
    • 2015-01-19
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2010-09-26
    • 2022-09-27
    相关资源
    最近更新 更多