2014-12-06 71 views
0

混乱比方说,我们有这两个阶级,一个主要的方法:约上溯造型和重载方法

public class Super { 
    public void f(double d){ 
     System.out.println("Super: f(double d)"); 
    } 
    public void f(int i){ 
     System.out.println("Super: f(int i)"); 
    } 
} 

public class Sub extends Super { 
    public void f(double d){ 
     System.out.println("Sub: f(double d)"); 
    } 

    public void f(float f){ 
     System.out.println("Sub: f(float f)"); 
    } 
} 

public class M { 
    public static void main(String[] args){ 
     Sub a = new Sub(); 
     a.f(1.5f); //output: "Sub: f(float f)" 

     Super b = new Sub(); 
     b.f(1.5f); //output: "Sub: f(double d)" 
    } 
} 

为什么第二个电话会导致Sub: f(double d)而不是像Sub: f(float f)的第一个?

当我添加

public void f(float f) { 
    System.out.println("Super: f(float f)"); 
} 

Super类,则输出变为Sub: f(float f)

鉴于这种行为,我希望的工作流程是这样的:

  1. 作为a被upcasted到Super,类Super检查的匹配方法
  2. 只有public void f(double d)被发现,所以浮子浇铸到一个双
  3. 现在方法public void f(double d)在更具体的类Sub看出并执行

这是正确的吗?

+1

因为没有方法'f(float)'可以通过'Super'类型的引用获得。 – 2014-12-06 21:01:15

回答

2

要理解此行为,请注意选择从编译时调用一系列重载方法的方法始终执行。但是,在运行时执行方法调度

因此,在编译时,只有double版本可见,但它将在运行时分派到子类的重写版本。

1

的方法b.f(1.5f)在编译时抬头。它的实现将在运行时是更具体的(如果存在),但是在编译时绑定了重载方法。

b由于是至少一个Super的唯一结论,编译器可以推断的是,该方法将是void f(double v)(因为Super不具有float过载),使得一个被选择。

然后在运行时实现是Sub类之一,由于动态绑定。