java - 在此代码中如何选择一种方法而不是另一种方法?

标签 java inheritance polymorphism

这是另一个 SCJP 问题。下面的代码打印出 Alpha:fooBeta:fooBeta:barBeta:bar,我不明白为什么第一个 foo 调用选择了 Alpha 的 foo 而不是 Beta 的。如果将 Alpha.foo 参数更改为 String 而不是 String...,则输出为 Beta:fooBeta:fooBeta:barBeta:bar,这是有道理的。

我的理解是,当您说 Alpha a = new Beta(); 时,编译器会检查 Alpha.foo,但 JVM 实际上会运行 Beta.foo。一方面,Beta 确实有一个 foo 方法,其签名与调用相匹配。另一方面,我认为可变参数方法仅在没有其他方法与调用匹配时才运行。所以这是我认为不应该运行 Alpha.foo 的两个原因。这种理解的哪一部分是错误的?

谢谢!

class Alpha {

    public void foo(String... args) { //if this were String args, then it makes sense
        System.out.print("Alpha:foo");
    }

    public void bar(String a) {
        System.out.print("Alpha:bar");
    } }

public class Beta extends Alpha {

    public void foo(String a) {
        System.out.print("Beta:foo");
    }

    public void bar(String a) {
        System.out.print("Beta:bar");
    }

    public static void main(String[] arg) {
        Alpha a = new Beta();
        Beta b = (Beta) a;
        a.foo("test");//confusing line
        b.foo("test");
        a.bar("test");
        b.bar("test");
    } }

编辑:我想我现在知道我在哪里误解了事情。我认为在 SuperClass sc = new SubClass(); 情况下,运行时在 sc 上调用的任何方法都会在 SubClass 中搜索,尽管它们会在编译时在 SuperClass 中搜索。事实证明,正如我现在认为我理解的那样,无论在 sc 上调用什么方法,都将在 编译时和运行时在 SuperClass 中搜索,除非 SubClass 提供了“更好”的版本的方法。然后,即使在编译时,编译器也会知道要调用的方法是子类版本。

最佳答案

带有 String[]String... 参数的方法和带有 String 参数的方法不共享相同的签名.字符串数组是一个完全独立的类型,因此它是一个标准的重载并且没有发生多态性。编译器认为它是类型“Alpha”的实例,并调用在那里找到的 foo 方法。 Beta 中的 foo 方法没有被调用,因为它实际上并不是 Alpha 版本的覆盖。

(这是 @Override 注释派上用场的地方。如果您尝试在 foo 的 Beta 版本上使用它,您会遇到编译器错误。 )

关于java - 在此代码中如何选择一种方法而不是另一种方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3795026/

相关文章:

java - 标记单词之间间距不等的行

java - 使用android studio IDE隐藏jar中方法的实现

java - 如何仅使用一个代码库对多个容器使用多种配置?

在for循环中创建的C++多态指针指的是同一个东西,这是因为我没有使用智能指针吗?

c++ - 确保dynamic_cast不会导致未定义的行为C++

java - Struts 中的 Json 插件和全局异常

python - Django:将公共(public)字段存储在父模型中

c# - 在 C# 中覆盖静态类

c++ - C++中Parents成员变量的继承?

c# - 使用运行时多态