Java 关于方法重写

Java 关于方法重写,java,overriding,Java,Overriding,对于下面的java代码段,“run”方法出现四次。我对这四次“跑”的关系感到相当困惑。原始代码相当长,我只保留了与我的问题相关的部分 1. public final class Job extends AbstractJob { 2. private Job( ) { 3. } 4. public static void main(String[] args) throws Exception { 5. new

对于下面的java代码段,“run”方法出现四次。我对这四次“跑”的关系感到相当困惑。原始代码相当长,我只保留了与我的问题相关的部分

   1. public final class Job extends AbstractJob {  
   2.   private Job( ) {  
   3.   }  
   4.   public static void main(String[] args) throws Exception {    
   5.            new Job( ).run(new Path("testdata"), output, 10 );  
   6.   }  
   7.   
   8.   @Override  
   9.   public int run(String[] args) throws IOException, ClassNotFoundException,      InterruptedException {  
  10.         run(input, output, alpha0);  
  11.         return 0;  
  12.   }    
  13.   public void run(Path input,  Path output,  double alpha0)  
  14.     throws IOException, ClassNotFoundException, InterruptedException {      
  15.     ClusterDriver.run(directoryInput, output, alpha0);      
  16.   }  
  17. }  
我可以如下理解这段代码的调用顺序吗

首先,调用第5行的run方法。由于其特殊的参数设置(3个参数),编译器会自动使用第13行中定义的run方法。(如果第5行中只有一个参数,那么编译器将使用第9行中定义的run方法

对于第9行中定义的run方法,它将在第10行调用run方法,这实际上是在第13行中定义的run方法


我的理解正确吗?

是的,它是正确的,只是这是方法重载,而不是重写

此类中定义了两个
run
方法,分别位于第9行和第13行,具有不同数量的参数。因此方法
run
被重载。(如果在子类中重新定义了一个虚拟基类方法,则会发生重写-很明显,在第9行定义的方法中会发生重写,正如其注释所证明的,但这在这个特定问题中不起作用。)


有两个对
run
(第5行和第10行)的调用,这两个调用都解析为使用3个参数(在第13行定义)调用方法。

只有最后一个run方法定义起作用


另一个run方法(采用
String[]
)调用此方法,因此它的行为类似于某种“代理”,而
main
方法中的另一个
run
调用可以选择调用这两种方法中的任何一种——“代理”run方法(采用
String[/code>)或者最后一个run方法,它实际上执行“running”操作。

您大部分操作都是正确的,但我想更正的语句很少:

if we only have one parameter in line 5, then compiler will use the run method defined in line 9 instead.
这并不完全正确,第9行的方法接受
String[]
类型参数,您需要传递一个数组来调用此方法

For the run method defined in line 9, it will call run method at line 10, which essentially is the run method defined at line 13.

在第10行,您将得到语法错误,因为该方法中未定义
input、output、alpha0
。您需要获取传递的
String[]args
参数,并将其转换为
input、output、alpha0
参数,以调用
run
的其他实现。您的基本分析是正确的

(为了澄清其他人提出的观点:重载是指方法具有相同的名称但签名不同,而重写是指方法与超类中的方法具有相同的名称和参数类型)

作为将来的参考,您应该知道,在重载方法的情况下,Java中的方法解析(名称+参数->方法选择)实际上可能很难理解。使用的确切行为在中有详细说明,并涉及一些基本细节:

  • 重载方法解析是在编译时完成的,而不是在运行时完成的。(根据最具体的子类的方法,在运行时对具有相同签名的方法重写进行选择。)如果编译器知道某个参数是
    Foo
    的实例(例如,其类是
    Foo
    Foo
    的子类)然后它将使用
    Foo
    作为参数的类,而不是它的“真实”类

  • 确定使用哪种方法的问题包括:

    • 方法是否为varargs(将
      ..
      作为最后一个参数,例如
      foo(对象a,字符串…b)
    • 方法的声明参数是原语还是包装原语,例如
      float
      vs
      float
    • 一个方法的声明参数是否比另一个“更具体”(子类比它们的超类更具体)

这很复杂,但您已经有了基本的理解。

这是关于方法重载,而不是重写。是的,您的理解是正确的。您看起来并不困惑,对我来说听起来不错。也许您缺乏信心。;)