将 child 转换为 parent - 由于缺少方法导致编译时错误 - 为什么?

Casting child to parent - compile time error due to missing method - why?

这是一个将 child class 转换为 parent,然后调用方法的简短示例。

我希望 foo 方法在 child class 中被调用,而不是 parent class。但是,我收到一个编译错误,指出 parent class 没有此方法。

如果我只在 child class 上调用它,为什么 Java 关心 parent class 是否有它?

public static void main(String[] args)
{
    A a = new A();
    B b = new B();

    b.foo(1, 2, 3); // Ok

    ((A) b).foo(1, 2); // Also ok. 
                       // Prints "In foo(int, int) method of class B"

    ((A) b).foo(1, 2, 3); // Will not compile

}

// 后面的代码...

class A 
{
    public int foo(int a, int b) 
    {
        System.out.println("In foo(int, int) method of class A");
        return 1;
    }
}

class B extends A 
{

    public int foo(int a, int b) 
    {
        System.out.println("In foo(int, int) method of class B");
        return 0;
    }
    public int foo(int a, int b, int c) 
    {
        System.out.println("In foo(int, int, int) method of class B");
        return -1;
    }
}

((A) b) 被视为 A,虽然它的 foo(int, int)B 的。

这意味着,因为 ((A) b) 被称为 A,您只能调用 A 拥有的方法。

A只有foo(int, int),所以不能调用foo(int, int, int).

您遇到的问题与方法重载的概念有关。

foo(int a, int b, int c) 不是 A 中的方法。尽管您定义的所有方法都具有相同的名称,但它们被视为单独的方法,因为它们各自具有不同数量的参数。

当您尝试调用 ((A) b).foo(1, 2, 3) 时,b 被视为 A 的实例。 Java 试图在 A 中使用 三个参数 找到一个名为 foo 的方法,但找不到它,因为它不存在。

((A) b).foo(1, 2, 3);

以上代码可以形象化为:

A a = (A)b;
a.foo(1, 2, 3);

正如你所看到的,这里的引用变量是'A'类型,所有的方法名称解析都应该基于'A'类型。具有三个参数(重载方法)的 foo(...) 在 A 中不存在,因此会引发错误。

((A) b).foo(1, 2); 之所以可行,是因为 A 具有具有匹配签名的方法 foo,但它执行 B 的 foo,因为在运行时 jvm 可以理解它正在使用 B 的实例。这在其他方法中不可用。

((A) b).foo(1, 2, 3); 
//is equivalent to
A b1 = new B();
b1.foo(1, 2, 3);

Java 是静态类型的,就编译器而言,您正试图对类型 A 和投诉调用不存在的方法。编译器不知道运行时类型是什么。