以下是关于我怀疑的代码信息。
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)
方法应该执行。
任何人都可以告诉我这种行为的正当理由吗?
提前致谢。
答案 0 :(得分:3)
在编译时实现对采用不同参数类型(重载)的方法的方法调用。 (这是你的情况)
如果所有3个方法都接受了类型A的参数 - 即方法覆盖,那么只有多态才会发挥作用并且会触发C
的方法,前提是存在继承关系在A和C之间,即C延伸A。
答案 1 :(得分:2)
决定使用哪种方法基本上有两个阶段:首先是重载决策,然后是方法调度。重载解析在编译时发生,在运行时调度方法。
在此示例中,重载决策决定应使用重载someMethod(A param)
,因为这是类someMethod
中定义的A
的唯一重载(以及{{1}的静态类型}是ac
)。
在运行时决定使用A
的哪个实现,但由于只有一个实现(someMethod(A param)
不覆盖C.someMethod(C)
,因为someMethod(A)
更具体C
),A
被选中。
答案 2 :(得分:0)
您编写的代码无法成功编译。你不能说“A ac = new C();”因为C不会扩展A.如果你声称已经运行了这个并获得了输出,那么你必须将正在运行的代码中的某些内容错误地复制到这篇文章中。
如果为了争论,你的代码确实说“A ac = new A();”,那么你的代码仍然无法运行,因为A.someMethod
需要A
,而不是一个C
。语句ac.someMethod(c)
执行函数A.someMethod
。 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中是非常不同的。