在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中,运算符重载实际上是多态还是参数重载?的主要内容,如果未能解决你的问题,请参考以下文章