如何知道在Java上的extends中执行的方法?
这是我的A类方法概述 让我们一步一步地看一下您的示例。您有三个类,如果我们列出它们的所有方法(包括重载和继承的方法),那么您有:如何知道在Java上的extends中执行的方法?,java,Java,这是我的A类方法概述 让我们一步一步地看一下您的示例。您有三个类,如果我们列出它们的所有方法(包括重载和继承的方法),那么您有: class A: void f (A a) -> prints "AA" // #1 void f (C c) -> prints "AC" // #2 class B: // from A void f (A a) -> prints "AA" // #3 void f (C c) -> prints
class A:
void f (A a) -> prints "AA" // #1
void f (C c) -> prints "AC" // #2
class B:
// from A
void f (A a) -> prints "AA" // #3
void f (C c) -> prints "AC" // #4
// from B, overload
void f (B b) -> prints "BB" // #5
class C:
// from B
void f (B b) -> prints "BB" // #6
// from C, overrides methods from A
void f (A a) -> prints "CA" // #7
void f (C c) -> prints "CC" // #8
因此,您的B
类定义了一个新的重载变量,该变量接受B
。C
类继承了A
和B
的所有内容,并且覆盖了A
的两种方法
解释 现在开始测试:
aa.f(ac); // AA
bb.f(ac); // AA
ab.f(bb); // AA
bb.f(ac); // AA
bb.f(cc); // CA
您的命名约定意味着实际实例是右字符类型,而您通过左字符类型的变量引用它。因此,ab
实际上是类B
的一个实例,并由允许引用a
类型的变量引用
知道了这一点,就很容易理解结果。第一个例子:
aa.f(ac); // AA
我们在A
类型的变量中有一个A
类型的实例。参数的类型为C
,变量的类型为a
。非常重要的是,请注意变量的类型将用于确定要选择的重载。因此,Java从#1
和#2
中选择#1
,因为ac
位于a
类型的变量中,而不是C
。由于使用了#1
,因此输出为“AA”
接下来的三次通话也会发生同样的情况,尽管第三次通话也很有趣:
ab.f(bb); // AA
虽然ab
实际上是一个B
实例,所以它有一个void f(B B B)
(#5
)打印“BB”
,我们看到“AA”
。这是因为ab
又是a
类型的变量。因此,编译器将查看a
提供的方法。唯一适用的方法是f(A)
(#1
),因为ab
绝对不是C
。因此,它再次使用#1
并打印“AA”
最后一个例子中的打字错误 你的最后一个例子有点不对劲。我猜你打错了,因为代码会输出
“AC”
,而不是“CA”
:
原因很简单bb
是B
类型,也是它的变量。因此,我们可以从B
s方法中进行选择(以及从A
继承的方法)。参数的类型为C
,其变量的类型相同。所以我们将方法#4
,printing“AC”
类型概述 以下是最终相关的实际类型情况:
A.f(A); // AA, #1
B.f(A); // AA, #3
A.f(B); // AA, #1
B.f(A); // AA, #3
B.f(C); // AC, #4
JLS定义 Java如何确定调用哪些方法的规则在Java语言规范中有明确定义。如果你感兴趣的话,你可以读它。相关章节如下所示。特别是和。部分摘录: 在类[…]中搜索可能适用于此方法调用的所有成员方法;从超类和超级接口继承的成员包括在此搜索中 如果一个方法调用可以访问并适用于多个成员方法,则有必要选择一个成员方法来为运行时方法分派提供描述符。Java编程语言使用的规则是选择最具体的方法
您能更清楚地说明您不了解的内容吗?那么您不了解的结果是什么?您需要研究多态性。另外,为什么“不使用Eclipse”?这看起来很武断。在上一个例子中,您可能有一个打字错误
bb.f(cc)
不能产生CA
因为bb
不是C
。结果是AC
。
aa.f(ac); // AA
ab.f(bb); // AA
bb.f(cc); // AC
A.f(A); // AA, #1
B.f(A); // AA, #3
A.f(B); // AA, #1
B.f(A); // AA, #3
B.f(C); // AC, #4