gpt4 book ai didi

java - 似乎无法理解复杂的多态性

转载 作者:太空狗 更新时间:2023-10-29 22:45:53 25 4
gpt4 key购买 nike

我正在学习 CS,我们有一些关于多态性的问题,我无法全神贯注。这是一个例子:

public class AA{
public AA(){
foo();
}
private void foo() {
System.out.print("AA::foo ");
goo();
}
public void goo(){
System.out.print("AA::goo ");
}
}

public class BB extends AA{
public BB(){
foo();
}
public void foo(){
System.out.print("BB:foo ");
}
public void goo(){
System.out.print("BB::goo ");
}
public static void main(String[] args){
// Code goes here
}
}

当在 void main 中时,我添加行:

AA a = new BB();

首先 AA 构造函数打印 AA:foo,然后 goo() 将它发送给 BB 的 goo,为什么这样?

简单的多态性,如“Animal -> cat/spider/dog”很容易理解,但说到这里我就迷路了。你们能给我一些如何阅读这段代码的提示吗?规则是什么?

编辑:没有@Override 注释,因为这是一道考试题。

最佳答案

解释

public class AA {

private void foo() { ... }
^^^^^^^

}

多态性不适用于private 方法。子类不继承 private 方法,因此它们不能被覆盖:

A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:

  • m is a member of the direct superclass of C.
  • m is public, protected, or declared with package access in the same package as C.
  • No method declared in C has a signature that is a subsignature of the signature of m.

Java Language Specification - 8.4.8. Inheritance, Overriding, and Hiding

因此,A 构造函数的 foo() 调用不会调用 BB#foo,它会调用 AA# foo.

但是 AA#foo 中的 goo() 调用引用了重写的方法 BB#goo。在这里,通过public 方法,应用了方法覆盖和多态性。


这有点棘手,所以我建议你把 @Override注释无处不在。

public class BB extends AA {

@Override // it doesn't compile - no overriding here
public void foo() { ... }
@Override // it does override
public void goo() { ... }

}

它也可能有助于检测另一个问题:

Programmers occasionally overload a method declaration when they mean to override it, leading to subtle problems. The annotation type Override supports early detection of such problems.

If a method declaration in type T is annotated with @Override, but the method does not override from T a method declared in a supertype of T, or is not override-equivalent to a public method of Object, then a compile-time error occurs.

Java Language Specification - 9.6.4.4. @Override

插图

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation super();, an invocation of the constructor of its direct superclass that takes no arguments.

Java Language Specification - 8.8.7. Constructor Body

简单来说,

public BB() {
foo();
}

变成

public BB() {
super();
foo();
}

牢记super();,我们可以做下图:

new BB()
AA() // super(); -> AA constructor
A#foo() // private method call
B#goo() // polymorphic method call
BB() // BB constructor
B#foo() // plain method call

关于java - 似乎无法理解复杂的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48881903/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com