JAVA程序的输出[多态性,方法重写]

JAVA程序的输出[多态性,方法重写],java,polymorphism,overriding,Java,Polymorphism,Overriding,我目前正在学习JAVA编程语言。在我的讲师笔记中,我发现了以下代码片段: class Base{ void g(){ System.out.print("g-Base "); } void f(){ System.out.print("f-Base "); g(); } } class Derived extends Base{ public static void main(String[] args) { Base b

我目前正在学习JAVA编程语言。在我的讲师笔记中,我发现了以下代码片段:

class Base{
   void g(){
     System.out.print("g-Base ");
   }
   void f(){
     System.out.print("f-Base ");
     g();
   }
}
class Derived extends Base{
   public static void main(String[] args) {
      Base b = new Derived();  b.f();
   }
   void g() {
      System.out.print("g-Derived ");
   }
   void f() {
      System.out.print("f-Derived "); super.f();
   }
}
问题是:这个程序的输出是什么。我编译并运行它,得到:f-Derived f-Base g-Derived
我了解f-Derived和f-Base部分,但为什么在最后一步中打印“g-Derived”,我认为它应该是“g-Base”。

让我们跟踪执行顺序:

  • Derived#f
    被调用并打印“f-Derived”
  • Derived#f
    然后调用
    super.f()
    ,这意味着
    Base#f
  • Base#f
    打印
    “f-Base”
  • Base#f
    然后调用
    g()
    。由于在
    Derived
    中重写了
    g()
    ,因此调用了
    Derived#g
  • Derived#g
    打印
    “g-Derived”

  • 编译器知道以下规则:

    如果调用方法时没有
    super
    关键字,则调用
    派生的
    
    版本,但如果使用
    super
    关键字调用方法,则调用
    Base
    版本


    因此,当调用
    super.f()
    时,调用
    f()
    Base
    版本,但当在
    Base
    版本内调用
    g()
    时,由于此调用没有
    super
    关键字(带有隐式
    this
    关键字,其中
    this
    派生的
    对象)编译器愉快地调用
    派生的
    版本,我们得到输出:
    g-Derived
    。希望这有帮助。

    就像
    Base b=new-Derived();b、 g()
    将打印
    g-Derived
    。是的,但是如果代码跳到super.f()并从那里调用g(),它是否应该继续从super调用g()?不,这是对
    this
    的动态调用(在运行时发生),即
    this.g()
    具有动态类型
    派生的
    ,因此将
    派生的::g
    称为.Hmm,这很有意义。我想我明白了,谢谢你的帮助:)但是编译器怎么知道,当Base#f调用g()时,它应该使用重写的g()而不是Base?我想我可能遗漏了一小部分逻辑。谢谢你的回答:)真棒的解释!谢谢!