Java中的动态方法调度
以下是关于我的疑问的代码snippletJava中的动态方法调度,java,polymorphism,Java,Polymorphism,以下是关于我的疑问的代码snipplet class A { void someMethod(A param) { System.out.println("A"); } } class C extends A { void someMethod(C param) { System.out.println("C"); } } class DMD { public static void main(String[] args
class A {
void someMethod(A param) {
System.out.println("A");
}
}
class C extends A {
void someMethod(C param) {
System.out.println("C");
}
}
class DMD {
public static void main(String[] args) {
A ac = new C();
C c = new C();
ac.someMethod(c);
}
}
输出:
A
但我把输出排除在外
C
因为我已经为C
分配了内存,A
引用C
的内存位置,所以如果我调用A
引用中指向C
的方法,并且参数作为C
类型传递,那么我希望someMethod(C)
方法应该执行
谁能告诉我这种行为的正当理由吗
提前感谢。决定使用哪种方法基本上有两个阶段:首先是过载解决,然后是方法调度。重载解析发生在编译时,方法调度发生在运行时 在此示例中,重载解析决定应使用重载
someMethod(参数)
,因为这是类A
中定义的someMethod
的唯一重载(而ac
的静态类型为A
)
运行时决定使用
somethod(A参数)
的哪个实现,但由于只有一个实现(C.somethod(C)
不会覆盖somethod(A)
,因为C
比A
更具体,A.somethod(A)
被选中。决定使用哪种方法基本上有两个阶段:首先是过载解决,然后是方法调度。重载解析发生在编译时,方法调度发生在运行时
在此示例中,重载解析决定应使用重载someMethod(参数)
,因为这是类A
中定义的someMethod
的唯一重载(而ac
的静态类型为A
)
运行时决定使用
somethod(A参数)
的哪个实现,但由于只有一个实现(C.somethod(C)
不会覆盖somethod(A)
,因为C
比A
更具体,A.somethod(A)
。对采用不同参数类型(重载)的方法的方法调用在编译时实现。(这就是你的情况)
如果所有3个方法都接受A类型的参数,即方法重写,则只有多态性才会发挥作用,并触发
C
方法,前提是A和C之间存在继承关系,即C扩展了A。对采用不同参数类型的方法的方法调用(重载)在编译时实现。(这就是你的情况)
如果所有3个方法都接受A类型的参数,即方法重写,则只有多态性才会起作用,并触发
C
方法,前提是A和C之间存在继承关系,即C扩展了A。编写的代码将无法成功编译。您不能说“A ac=new C();”,因为C并没有扩展A。如果您声称运行了此程序并获得了输出,那么您一定是将正在运行的代码中的某些内容错误地复制到了本文中
如果为了论证,您的代码确实说了“A ac=new A();”,那么您的代码仍然不会运行,因为A.someMethod
采用的是A
,而不是C
。语句ac.somethod(c)
执行函数A.somethod
ac
属于A
类型,因此对ac
执行任何函数都将从类A
中获得该名称的函数。尝试将类型为C
的参数传递给声明为接受类型为a
的参数的函数不会“切换”到使用其他类中接受此类参数的函数。重载只在类中有效
也许你想的是一个更像这样的例子:
class A {
public void someMethod(A a) {
System.out.println("A");
}
public void someMethod(B b) {
System.out.println("B");
}
}
class Dmd {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.someMethod(b);
}
}
这将输出“B”
这里的区别在于类A
有两个版本的函数someMethod
。其中一个取A
,一个取B
。当我们用B
调用它时,我们得到了B
版本
你知道这和你的例子有什么不同吗?您正在声明三个类,每个类都有一个函数
someMethod
。这里我们有一个类,它有两个函数,都名为someMethod
。这在Java中非常不同。您编写的代码无法成功编译。您不能说“A ac=new C();”,因为C并没有扩展A。如果您声称运行了此程序并获得了输出,那么您一定是将正在运行的代码中的某些内容错误地复制到了本文中
如果为了论证,您的代码确实说了“A ac=new A();”,那么您的代码仍然不会运行,因为A.someMethod
采用的是A
,而不是C
。语句ac.somethod(c)
执行函数A.somethod
ac
属于A
类型,因此对ac
执行任何函数都将从类A
中获得该名称的函数。尝试将类型为C
的参数传递给声明为接受类型为a
的参数的函数不会“切换”到使用其他类中接受此类参数的函数。重载只在类中有效
也许你想的是一个更像这样的例子:
class A {
public void someMethod(A a) {
System.out.println("A");
}
public void someMethod(B b) {
System.out.println("B");
}
}
class Dmd {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.someMethod(b);
}
}
这将输出“B”
这里的区别在于类A
有两个版本的函数someMethod
。其中一个取A
,一个取B
。当我们用B
调用它时,我们得到了B
版本
你知道这和你的例子有什么不同吗?您正在声明三个类,每个类都有一个函数someMethod
。这里我们有一个类和两个函数,都名为someMetho