如何知道在Java上的extends中执行的方法?

如何知道在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

这是我的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 "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