将 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 和投诉调用不存在的方法。编译器不知道运行时类型是什么。
这是一个将 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 和投诉调用不存在的方法。编译器不知道运行时类型是什么。