- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的问题可能不是很清楚。通过这个例子,我可以进一步解释。当我阅读为此发布的答案时Static vs Dynamic Binding Logic ,我有这个问题。
有两个版本的代码,除了Class B p (double i)的参数类型发生变化
之外,两者完全相同。
version 1:
import java.lang.*;
public class X
{
public static void main(String [] args)
{
B c = new A();
c.p(10);
c.p("AAA");
((A)c).p(10);
}
}
class B {
public void p(String s)
{
System.out.println("B: my string is " + s);
}
public void p(int i)
{
System.out.println("B: twice my double is: " + i*2);
}
}
class A extends B{
public void p(int i)
{
System.out.println("A: my number is " + i);
}
}
Here the output is :
A:my number is 10
B: my string is AAA
A: my number is 10
version 2:
import java.lang.*;
public class X
{
public static void main(String [] args)
{
B c = new A();
c.p(10);
c.p("AAA");
((A)c).p(10);
}
}
class B {
public void p(String s)
{
System.out.println("B: my string is " + s);
}
public void p(double i)
{
System.out.println("B: twice my double is: " + i*2);
}
}
class A extends B{
public void p(int i)
{
System.out.println("A: my number is " + i);
}
}
Here the output is :
B:twice my double is 20.0
B: my string is AAA
A: my number is 10
我的问题如下:为什么在第一个版本中调用 A 类的 p(int)
而在第二个版本中调用 B 类的 p(double)
。
version 1:
methods of A
A -----> p(string), p(int)- this is overridden from Class B
method of B
B ------> p(string), p(int)
version 2:
methods of A
A -----> p(string), p(double), p(int) No more overriding
method of B
B ------> p(string), p(double)
当我声明 B c;
时,我初始化了 B
类型的引用变量
接下来我将 c 分配给新对象,通过 c = new A();
因此这个声明B c = new A();
创建了类A的一个实例并分配给B类型的变量。现在每当在c上执行方法调用时,编译器首先检查方法是否存在于B中(因为它是B类型),但实际调用的方法是对象的方法(它是A实例)。为什么在上面的例子中没有看到这种行为?或者如果我的推理有误,请纠正我。
谢谢
最佳答案
在第一个版本中,您重写一个方法,在第二个版本中,您重载它。
在第一个版本中,A 类
和B 类
中都有p
。当您调用 c.p(...)
时,编译器使用 c
的静态类型来创建调用。在运行时,代码使用类的虚拟表(如果您不熟悉,请阅读相关内容)来找到正确的多态方法。
在第二个版本中,编译器在编译时为您执行从 int 到 double 的转换,然后在运行时再次使用 A
的虚拟表来查找具有签名 p(double)
的方法(因为它在编译时将 int 转换为静态类型合规性)。虚拟表指向 B
中的方法,因为 A
不会覆盖它。
您可以在《Effective Java》一书中进一步了解它 - 第 41 项,第 191 页:
重载方法的选择是静态的,而重写方法的选择是动态的
关于java - Java中什么时候调用对象类型而不是对象的方法,特别是在静态绑定(bind)中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18369158/
我已经可以在其中输入一些附加文本了mydomain/wiki/Special:UserLogin。我添加了一句话: In order to apply for an account send an m
有人可以解释以下脚本输出背后的逻辑吗? import numpy if(numpy.dtype(numpy.float64) == None): print "Surprise!!!!" 谢谢
是我还是 gmail bulls**t?在 outlook/浏览器上,我的电子邮件是完美的,但在 gmail 上,2 个表之间有一个空间,为什么?!?图片:http://i.imgur.com/srJ
我是一名优秀的程序员,十分优秀!