【问题标题】:Dynamic method dispatching in Java [duplicate]Java中的动态方法调度[重复]
【发布时间】:2017-03-28 18:07:38
【问题描述】:

以下是关于我的疑问的代码片段。

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) 方法应该执行。

谁能给我这种行为的正当理由?

提前致谢。

【问题讨论】:

  • 因为 C 没有扩展 A,所以无法编译。
  • 这与正则表达式无关

标签: java polymorphism


【解决方案1】:

对采用不同参数类型(重载)的方法的方法调用是在编译时实现的。 (这是你的情况)

如果所有 3 个方法都接受类型 A 的参数 - 即方法 覆盖 存在,那么只有当 A 之间存在继承关系时,多态才会发挥作用并触发 C 的方法和 C 即 C 扩展 A.

【讨论】:

    【解决方案2】:

    决定使用哪个方法基本上有两个阶段:首先是重载解决,然后是方法分派。重载解析发生在编译时,方法调度发生在运行时。

    在这个例子中,重载决议决定应该使用重载someMethod(A param),因为这是someMethod在类A中定义的唯一重载(ac的静态类型是A)。

    在运行时决定使用someMethod(A param) 的哪个实现,但由于只有一个实现(C.someMethod(C) 不会覆盖someMethod(A),因为CA 更具体),A.someMethod(A)被选中。

    【讨论】:

      【解决方案3】:

      您编写的代码将无法成功编译。你不能说“A ac = new C();”因为 C 没有扩展 A。如果您声称已经运行了它并获得了输出,那么您一定是在运行代码中错误地将某些内容复制到了这篇文章中。

      如果,为了争论,你的代码真的说“A ac = new A();”,那么你的代码仍然不会运行,因为A.someMethod 接受A,而不是C .语句ac.someMethod(c) 执行函数A.someMethodacA 类型,因此对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 中非常不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 2013-07-11
        • 1970-01-01
        相关资源
        最近更新 更多