Java 在继承中使用时与访问修饰符混淆
我一直在编写这段代码,但我无法理解为什么某些访问修饰符可以工作,而有些则不能:Java 在继承中使用时与访问修饰符混淆,java,overloading,overriding,Java,Overloading,Overriding,我一直在编写这段代码,但我无法理解为什么某些访问修饰符可以工作,而有些则不能: 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 inh
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行和第4行是不允许的
我尝试过搜索,但没有找到明确的解释,尽管我确实找到了以长或2个整数作为参数的方法(3,5,6,7)没有覆盖Blip方法,因为方法签名(名称和参数的组合)不同 第1行很好,因为它增加了方法的可见性。 相反,第2行失败了,因为它降低了方法的可见性
第4行不起作用,因为返回值不同,并且不是以更具体的方式。返回原语时,返回值不能更改。但是,当返回对象时,子类可以返回更具体的类。例如,
Cloneable.clone()
返回一个对象。实际的实现可以随意更改以返回任何类型的对象。首先,我认为您的注释并不完全正确
除了访问修饰符之外,方法重载的概念也在这里发挥作用
方法重载允许您在同一类中定义具有相同名称的多个方法,如果它们具有不同的签名,即不同数量或类型的参数
请记住,返回类型不是方法签名的一部分。(我留给您从语言文档中找出某些兼容性问题)
因此,在这种情况下:
1有效:因为它是名为blipvert的方法的第一个实现。
2不起作用:因为已经定义了具有相同签名的公共方法。
3工作:1中定义的方法重载,参数类型不同。
4不起作用:由于与2相同的原因,已经定义了更广泛的访问方法。
5不起作用:因为已经定义了具有相同签名的公共方法。
6不起作用:因为已经定义了具有相同签名的公共方法。
7个工作:使用不同数量的参数重载
在编译器上测试它。我是在javac1.7.0_09上做的。除非您注释除1、3和7之外的所有内容,否则它将无法编译 签名在编译时绑定,包含:类、方法名和参数
这意味着,您不能有两个相同的签名,如:
- Vert.blipvert(int)//来自返回int的inharitance
- Vert.blipvert(int)//返回long
而且你不能有:
- 垂直blipvert(int)//来自受保护的先天
- blipvert(int)//哪个是私有的
您可能想知道,为什么它不重写方法?通常是这样,但继承意味着父级中定义的所有方法也可以在chlid中使用
注意:普通的签名会在包中给出完整的类名,而不仅仅是部分的,但是我这样写的话,看起来会过于复杂。这里有很多概念。我投票赞成太宽的范围。但是,请注意,方法重载和返回类型的兼容性。这是一个很好的例子,说明了使用注释方法的好处-编译器将为您确认您正在注释的方法实际上覆盖了父方法。在开发过程中,明确您期望的行为将大大减少这种混乱。请参阅,返回类型不是方法签名的一部分。看:最后第二行。它们有点像。如果更改方法的返回类型,您将进行二进制非被动更改,甚至从集合
更改为列表
或集合
。我承认这应该是我懒得做的细致描述。