Rob*_*ert 17 java oop syntax inheritance overloading
我不明白这种Java行为.我有两节课:
class C1 {
public void m1(double num) {
System.out.println("Inside C1.m1(): " + num);
}
}
class C2 extends C1 {
public void m1(int num) {
System.out.println("Inside C2.m1(): " + num);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的主要内容:
public class Main {
public static void main(String[] args) {
C1 c = new C2();
c.m1(10);
}
}
Run Code Online (Sandbox Code Playgroud)
结果是:
Inside C1.m1(): 10.0
Run Code Online (Sandbox Code Playgroud)
当我预料到:
Inside C2.m1(): 10
Run Code Online (Sandbox Code Playgroud)
当我尝试完成代码语法时,我发现了这个:
C2类的其他m1在哪里?
我还检查了我的Main.class的字节码,我看到了这个:
Compiled from "Main.java"
public class com.company.Main {
public com.company.Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class com/company/C2
3: dup
4: invokespecial #3 // Method com/company/C2."<init>":()V
7: astore_1
8: aload_1
9: ldc2_w #4 // double 10.0d
12: invokevirtual #6 // Method com/company/C1.m1:(D)V
15: return
}
Run Code Online (Sandbox Code Playgroud)
字节码告诉我它将调用C1.m1(D)V(第12行).
为什么C1的方法?我试图理解这种行为.
chr*_*ke- 16
你命名的两个方法m1
没有相同的签名; 超类中的一个取一个double
,而子类中的一个取一个int
.这意味着编译器将根据变量的编译时类型选择要调用的方法签名,这将是C1
,并且将调用m1(double)
.由于在运行时该类C2
没有重写版本m1(double)
,因此C1
调用了版本.
规则是在编译时基于编译时类型计算方法签名 ; 方法调用在运行时根据匹配的签名进行调度.
为什么你看到的输出的原因Inside C1.m1(): 10.0
,而不是Inside C1.m1(): 10
或者Inside C2.m1(): 10.0
是因为:
m1
在C2
.你是超负荷m1(doube)
您从继承的方法C1
来m1(int)
代替.C2
课程现在有两种m1
方法.一个inherited
来自C1
并且具有签名m1(double)
,一个被重载C2
并且具有签名m1(int)
c.m1(10)
,它会根据引用类型解析此调用.由于引用类型是C1
,编译器将解析此调用m1(double)
in C1
.m1(double)
在C2
这是从继承方法C1
.(如第2点所述)有两种m1(int)
方法可以调用该方法:
((C2)c).m1(10);
要么
C2 c = new C2();
c.m1(10);
归档时间: |
|
查看次数: |
2490 次 |
最近记录: |