在OOP中,运算符重载实际上是多态还是参数重载?

Posted

技术标签:

【中文标题】在OOP中,运算符重载实际上是多态还是参数重载?【英文标题】:In OOP, is operator overloading in fact polymorphism or parameter overloading? 【发布时间】:2011-07-24 11:34:11 【问题描述】:

运算符重载实际上是多态还是参数重载?

是不是多态通常是指不同的类响应同一个“消息”(方法名),做不同的事情,所以

bird.give_sound()

car.give_sound()

可以做不同的事情。而参数重载更多的是讲同一个类,当随消息发送的参数(方法名)不同时做不同的事情。所以

bird.give_sound()

bird.give_sound(:frighten_sound)

可以不同。

所以运算符重载是严格的参数重载?像下面这样:

"foo" + "bar"
"foo" + 3

至少在Ruby中,它是将+消息发送到包含foo的字符串,第一行是带参数字符串发送,第二行是发送参数3,+稍微做一点不同的东西,但它是同一个接收器类String

在下面的例子中,就是多态性:

"foo" + 3
1 + 3

因为+消息调用不同类的不同方法,但使用相同的消息名称+。那么在这两种情况下,它们是多态,而不是运算符重载?

以上是否准确无误?上面有什么可以添加或更正的吗?

【问题讨论】:

我会说你是对的,但谁在乎呢? :-D 只是为了搞明白,很久以前有个面试官问我什么是多态和重载,详细的区别是什么... 【参考方案1】:

感谢您在评论中澄清上下文。是的,我会说你是对的。

尽可能简短地总结...

给定相同的方法名称(或“消息”):

基于参数类型的不同行为是重载, 基于对象类型的不同行为是多态性。

【讨论】:

【参考方案2】:

我要在黑暗中试一试,说它有点(但不是真的)两者兼而有之。

每个对象都必须以特定的方式处理给定的对象(运算符右侧的对象)。对于字符串,似乎会使用toString 方法(或其他语言等效项)。所以你总是会附加一个字符串(作为Object 传递给方法)。 (多态性)

但是,您的对象可能需要根据给定的对象执行不同的逻辑。例如,假设您有一个 Student 对象。您可能有一个版本的方法,它采用Class 对象,并将其添加到学生的课程表中。然后,您可能会有一个过载,例如,Book 并将其添加到学生所需阅读材料的集合中。 (参数重载)

【讨论】:

【参考方案3】:

多态是指一种​​数据类型动态地表现为另一种数据类型。(动态类型转换)

Shape
  Qudrilateral
    Rect
    Rhombus
  Elliptoid
    Oval
    Circle

多态会自动为给定的对象上下文选择合适的 area() 方法

运算符重载是当您为方法上下文选择正确的区域方法时(即传递的参数数量或传递的参数类型)因此,如果 Rect 有两个区域方法,一个接受一个参数(正方形),一个接受两个参数(任何其他矩形)

因此,根据使用上下文,为给定对象定义运算符可能会导致多态性或运算符重载。

【讨论】:

【参考方案4】:

好问题。

您发现的问题是,我们有两个不同的概念,它们的语法相似,在应用编程时会发生冲突:重载和参数继承。

当我发现运算符重载时,我通常会从重载(方法)函数的角度来考虑,以便更清楚。

当我读到这些时:

// (string) x = (string) "foo" + (int) 3 x = "foo" + 3

我想到了这些:

// (string) x = (string) "foo".concat((int) 3) x = "foo".concat(3)

还有一个额外的问题,即每种编程语言处理具有不同类的运算符。

我建议,避免使用对象参数重载运算符,并明确使用函数。

【讨论】:

以上是关于在OOP中,运算符重载实际上是多态还是参数重载?的主要内容,如果未能解决你的问题,请参考以下文章

C++ | 运算符重载

重载的编程语言中的重载

重载与重写

java中重载,继承,重写和多态的区别

6多态性-2运算符重载

C++ 多态相关