Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在继承中使用时与访问修饰符混淆_Java_Overloading_Overriding - Fatal编程技术网

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中使用


注意:普通的签名会在包中给出完整的类名,而不仅仅是部分的,但是我这样写的话,看起来会过于复杂。

这里有很多概念。我投票赞成太宽的范围。但是,请注意,方法重载和返回类型的兼容性。这是一个很好的例子,说明了使用注释方法的好处-编译器将为您确认您正在注释的方法实际上覆盖了父方法。在开发过程中,明确您期望的行为将大大减少这种混乱。请参阅,返回类型不是方法签名的一部分。看:最后第二行。它们有点像。如果更改方法的返回类型,您将进行二进制非被动更改,甚至从
集合
更改为
列表
集合
。我承认这应该是我懒得做的细致描述。