【问题标题】:Java: why is this function never called?Java:为什么这个函数从来没有被调用过?
【发布时间】:2012-10-24 12:54:56
【问题描述】:
package main;

class F {
    void f() {
        System.out.print("F.f() ");
        this.g();
    }

    void g() {
        System.out.print("F.g() ");
    }
}

class Fbis extends F {
    void f() {
        System.out.print("Fbis.f() ");
        this.g();
    }

    void g() {
        System.out.print("Fbis.g() ");
        super.f();
    }
}

public class Main {
    public static void main(String[] args) {
        F f = new Fbis();
        ((F) f).f();
    }
}

您好,我想了解为什么 F 类中的 g() 函数从未被调用过。 这段代码可以编译并运行,但会导致一个无限循环,显示如下:

Fbis.f() Fbis.g() F.f() Fbis.g() F.f() Fbis.g() F.f() Fbis.g() F.f() Fbis.g() F.f() Fbis.g() F.f() Fbis.g() F.f() Fbis.g() F.f() ...

那么会发生什么,是调用了Fbis.f,它调用了Fbis.g,它调用了F.f,而不是调用F.gF.f调用了Fbis.g

【问题讨论】:

  • @FranzEbner 只有在他使用 Eclipse 时才有效;-)
  • @André Playbutton vs. Shell... Playbutton 获胜:D
  • @FranzEbner 当然。 Eclipse 很棒,我自己也在使用它。只是说:-)

标签: java class inheritance compilation


【解决方案1】:

基本上,这就是继承的工作原理。 Fbis 类覆盖 g() 方法,因此对于任何 Fbis 实例调用 g() 将运行 Fbis 类中的代码,即使它是从 F 类本身中调用的。

这通常是可取的行为。例如,想象一个delete() 方法。在父类中,当您的应用程序删除对象时,这会进行一些清理。在子类中,它会针对这个孩子进行额外的清理。您可能希望在调用 delete() 时进行额外的清理,即使这是来自父类中的。

【讨论】:

    【解决方案2】:

    F.f 但不是调用 F.g,而是 F.f 调用 Fbis.g.

    你的代码说

    void f(){System.out.print("F.f() ");this.g();}
    

    这意味着F.f()应该调用这个类实现的类的g();

    如果你想让 Fbis.g 调用 F.g 你会写

    void g(){System.out.print("Fbis.g() "); super.g();}
    

    【讨论】:

    • 我认为他正在考虑调用 this.g()F.f() 最终是 Fbis.g()
    【解决方案3】:

    当您覆盖一个方法时,无论您从哪里调用它,都会始终使用被覆盖的版本。

    当你在基类中做this.g(),并且当前对象属于一个子类时,你在子类中调用g()

    当您在基类中有任何从基类调用的方法,并且您不想让它们被派生类替换时,您应该将该方法设为私有且最终的。

    【讨论】:

      【解决方案4】:

      您的 Fbis 类将覆盖方法 g()。如果您创建Fbis 的新对象,则名为g 的唯一方法是Fbis 中定义的方法。即使您从继承的方法中调用它,它仍然是唯一的方法。否则说如果你创建了一个Fbis 对象this 指向该对象,如果它在超类中使用也是如此。

      【讨论】:

        【解决方案5】:

        F.g() 方法不再存在于 Fbis 中!

        因为您正在“覆盖” Fbis 中的 g() 方法。了解仅使用“super.g”将保留覆盖。

        【讨论】:

          【解决方案6】:
          class F {
              void f() {
                  System.out.print("F.f() ");
                  this.g(); //<----- This line calls Fbis.g() not F.g() 
                            // because this is the instance of Fbis
              }
          

          【讨论】:

            猜你喜欢
            • 2011-11-16
            • 1970-01-01
            • 2013-10-19
            • 2019-06-28
            • 2020-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多