Java中的动态方法调度

Java中的动态方法调度,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

以下是关于我的疑问的代码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) {
        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