【发布时间】:2018-03-28 11:56:16
【问题描述】:
关于接收器参数上下文中覆盖等效 (JLS 8.4.2) 的定义,我有一个相当技术性的问题。
编辑:发布此问题后,cmets 对接收器参数有很多困惑。许多人似乎认为在下面的代码中有一个名为this 的参数是非法的,因此误解了这个问题。如果您不了解此功能,请参考https://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.4.1。在这里可以找到一个可能更容易理解的解释:http://blog.joda.org/2015/12/explicit-receiver-parameters.html。这个问题技术性很强,针对的是经验丰富的 Java 开发人员,他们熟悉接收器参数并熟悉 Java 语言规范 (JLS)。
override-equivalent 定义如下:
m1方法的签名是m2方法签名的子签名,如果:
m2与m1具有相同的签名,或者m1的签名与m2签名的擦除(§4.6)相同。如果
m1是m2的子签名或m2是m1的子签名,则两个方法签名m1和m2是等效的。 p>
因此,如果我理解正确,以下类中的两个方法不是重写等效的,尽管直观地说,我希望它们是:
class A {
void foo(A this) { /* ... */ }
void foo() { /* ... */ }
}
尽管如此,显然我不能在同一个类中声明这两个方法,当我尝试这样做时,编译器理所当然地抱怨 foo() 已定义。
我的问题由两部分组成:
- 我是否正确理解上述两种方法不是覆盖等效的?
- 如果不是:我错过了定义的哪一部分?
- 如果是:JLS 中的什么规则正式禁止上述两个方法定义同时出现在同一个类中,因为在这种情况下它不能是规则 “声明两个是编译时错误类中具有重写等效签名的方法。" (JLS 8.4.2)
【问题讨论】:
-
如果它们没有相同的参数,则不是覆盖,而是重载。您不能覆盖同一类中的方法,只能在子类中覆盖
-
@Stultuske 我不确定您所说的“他的意思是当它们都具有相同的参数时”。我的意思是上面发布的两种确切方法。显然,它们不能共存。因此,我也不会将此方法称为“重载”。
-
问题是你不明白“this”在这个上下文中是什么意思。两个签名都没有参数。
-
@MalteSkoruppa 您不能使用“this”作为变量名。上面的代码不会'编译。给它一个有效的名称,它会工作
-
您的问题应该引起更多关注,因为它与接收器参数有关。 99% 的 Java 开发人员不知道它们的存在。
标签: java overriding