从c++到Java,一个显而易见的未回答的问题是为什么Java没有包含操作符重载?
复合物不是a b c吗?A = b + c;比复合物a, b, c简单得多;A = b.add(c);?
是否有一个已知的原因,不允许操作符重载的有效参数?理由是随意的,还是被时间消磨了?
从c++到Java,一个显而易见的未回答的问题是为什么Java没有包含操作符重载?
复合物不是a b c吗?A = b + c;比复合物a, b, c简单得多;A = b.add(c);?
是否有一个已知的原因,不允许操作符重载的有效参数?理由是随意的,还是被时间消磨了?
当前回答
我认为这可能是一个有意识的设计选择,迫使开发人员创建的函数的名称清楚地表达了他们的意图。在c++中,开发人员会用与给定操作符的普遍接受性质无关的功能重载操作符,这使得不查看操作符的定义几乎不可能确定一段代码的功能。
其他回答
有时,操作符重载、友类和多重继承会很好。
然而,我仍然认为这是一个很好的决定。如果Java有运算符重载,那么如果不查看源代码,我们就永远无法确定运算符的含义。目前还没有必要。而且我认为你使用方法而不是操作符重载的例子也是相当可读的。如果你想让事情更清楚,你总是可以在烦人的语句之上添加注释。
// a = b + c
Complex a, b, c; a = b.add(c);
假设Java是实现语言,那么a、b和c都是对初始值为null的Complex类型的引用。还假设Complex是不可变的,就像前面提到的BigInteger和类似的不可变BigDecimal一样,我想你是指下面的意思,因为你将引用赋值给从添加b和c返回的Complex,而不是将这个引用与a进行比较。
不是: 复合物a, b, c;A = b + c; 简单得多: 复合物a, b, c;A = b.add(c);
这不是一个很好的理由来禁止它,而是一个实际的理由:
人们并不总是负责任地使用它。请看下面这个来自Python库scapy的例子:
>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=TCP |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=55 |<TCP |>>
下面是解释:
/操作符用作两个操作符之间的复合操作符 层。当这样做时,下层可以有一个或多个它的 默认字段根据上层重载。(你仍然 可以给出你想要的值)。字符串可以用作原始层。
你可能真的会搬起石头砸自己的脚。这就像指针一样,人们会犯愚蠢的错误,所以我们决定把剪刀拿走。
至少我认为这是原因。 反正我是站在你这边的。:)
我认为这可能是一个有意识的设计选择,迫使开发人员创建的函数的名称清楚地表达了他们的意图。在c++中,开发人员会用与给定操作符的普遍接受性质无关的功能重载操作符,这使得不查看操作符的定义几乎不可能确定一段代码的功能。