如何解决Java重载和重载方法
在下面的程序中,我在A类中有一个方法被重载了3次,然后在子类B中,这3个重载方法都被覆盖。
obj3是具有引用类型A(超类)和对象类型B(子类)的对象,它在执行时从B调用该方法,这是预期的行为。
由于此代码中同时存在重载和重载,这是否意味着它在编译时执行了静态绑定(到A类中的匹配方法),然后在运行时执行了动态绑定(到B类中的方法)。它们可以一起出现吗?
我的假设是这是动态绑定的经典案例,因为我认为“绑定”是永久性动作,但同行认为这两者是在一起的(首先是静态,然后是动态)。
class A{
public void method(Integer n){
System.out.println("Integer: "+n);
}
public void method(String s){
System.out.println("String: "+s);
}
public void method(String s,Integer n){
System.out.println("String: "+s+" Integer: "+n);
}
}
class B extends A{
public void method(Integer n){
System.out.println("Integer(from B): "+n);
}
public void method(String s){
System.out.println("String(from B): "+s);
}
public void method(String s,Integer n){
System.out.println("String(from B): "+s+" Integer(from B): "+n);
}
}
public class Test{
public static void main(String[] args){
A obj1 = new A();
B obj2 = new B();
A obj3 = new B();
System.out.println("Integer form of method");
// Integer form of method
System.out.println("Ref A Obj A");
// Ref A Obj A
obj1.method(1);
// Integer: 1
System.out.println("Ref B Obj B");
// Ref B Obj B
obj2.method(2);
// Integer(from B): 2
System.out.println("Ref A Obj B");
// Ref A Obj B
obj3.method(3);
// Integer(from B): 3
}
}
解决方法
您说对了。编译器在类A
中的重载之间进行静态选择,并将该信息以FQN方法的形式放入.class
文件中。
然后运行时在该方法的实现之间动态选择。
,由于此代码中同时存在重载和重载,这是否意味着它在编译时执行了静态绑定(对A类中的匹配方法),然后在运行时进行了动态绑定(对B类中的方法)
对。编译器根据变量的类型(在这种情况下为A
)选择了匹配的签名,这是静态的。
在运行时,Java查找编译器选择的签名的实现。这是动态的,基于obj3
(在这种情况下为B
)的运行时类。
再进行一次澄清:
超载
重载意味着单个类具有不同参数类型(又称签名)的多个方法,而您刚好给它们使用了相同的名称。如果您将方法更改为单独的名称,例如methodI(Integer n)
,methodS(String s)
和methodSI(String s,Integer n)
。
或者,您可以想象编译器在内部始终将这样的类型列表附加到方法名称上。
重载由编译器根据参数表达式的编译时类型解决。
例如如果你写
Object par = "Test";
a.method(par);
您收到编译器错误。即使我们都看到您正在传递给方法的是String
,编译器也只会看到Object
,并且找不到匹配的方法。仅当您要引入一个附加的method(Object o)
时,编译器才会选择那个。然后运行时将调用该方法,而不是String版本!
覆盖
覆盖意味着在运行时JVM根据“点之前的对象” 的运行时类调用方法实现。
在这种情况下,“方法”将被读取为编译器发现与参数列表匹配的重载方法版本。因此,运行时已经知道是methodI()
,methodS()
还是methodSI()
的意思,并且仅决定从哪个类中获取实现。
个人意见
允许多个方法共享相同的名称,但参数列表不同(又名重载),会产生太多混淆,以致于其好处。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。