我一直在研究这段代码,但我无法弄清楚为什么某些访问修饰符有效,有些则无法解决:
public class Base {
protected int method(int x) { return 0; }
}
class Child extends Base {
// Line 1: Compiles
public int method(int x) { return 0; }
// Line 2: Cannot reduce the visibility of the inherited method from Base
private int method(int x) { return 0; }
// Line 3: Compiles
private int method(long x) { return 0; }
// Line 4: The return type is incompatible with Base.method(int)
protected long method(int x) { return 0; }
// Line 5: Compiles
protected int method(long x) { return 0; }
// Line 6: Compiles
protected long method(long x) { return 0; }
// Line 7: Compiles
protected long method(int x, int y) { return 0; }
}
我试图理解为什么允许第1,3,5,6和7行,但第2和第2行是4不是。
虽然我确实找到了In Java, difference between default, public, protected, and private
,但我还是尝试过搜索,但没有找到明确的解释答案 0 :(得分:1)
采用long或2 int作为参数(3,5,6,7)的方法不会覆盖Blip方法,因为方法签名(名称和参数的组合)不同。
第1行很好,因为它增加了方法的可见性。 相反,第2行失败,因为它降低了方法的可见性。
第4行无效,因为返回值不同,而不是更具体的方式。返回基元时,返回值不能更改。但是,在返回对象时,子类可以返回更具体的类。例如,Cloneable.clone()
会返回Object
。实际的实现可以随意更改它以返回任何类型的Object。
答案 1 :(得分:0)
首先,我认为你的笔记并不完全正确。
除了访问修饰符之外,方法重载的概念也在这里发挥作用。
方法重载允许您在同一个类中定义具有相同名称的多个方法(如果它们具有不同的签名,即不同数量或类型的参数)。
请记住,返回类型不是方法签名的一部分。(我有一些兼容性的怪癖可以让你从语言文档中找出来)
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
所以在这种情况下:
1有效:因为它是名为blipvert的方法的第一个实现 2不起作用:因为已经定义了具有相同签名的公共方法 3作品:1中定义的方法的重载,具有不同的参数类型 4不起作用:出于与2相同的原因,已经定义了更广泛的访问方法 5不起作用:因为已经定义了具有相同签名的公共方法 6不起作用:因为已经定义了具有相同签名的公共方法 7个工作:使用不同数量的参数进行重载。
在编译器上测试它。我在compileonline的Javac 1.7.0_09做了。除非您评论除1,3和7之外的所有内容,否则它将无法编译。
答案 2 :(得分:0)
签名在编译时绑定包含:类,方法名称和参数
这意味着,您不能拥有两个相同的签名,如:
并且您也无法:
您可能想知道,为什么它不会覆盖方法? Normaly确实如此,但继承意味着父母中定义的所有方法也可用于chlid。
注意:Normaly签名会给包的完整类名,而不仅仅是部分的,但imho这样写,会看起来过于复杂。