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.g
,F.f
调用{{ 1}}。
答案 0 :(得分:9)
基本上,这就是继承的工作原理。 Fbis
类会覆盖g()
方法,因此Fbis
调用g()
的任何实例都会运行Fbis
类中的代码,即使这是从内部调用的F
类本身。
这通常是理想的行为。例如,假设一个delete()
方法。在父类中,当应用程序删除对象时,这会进行一些清理。在儿童班中,它为这个孩子做了额外的清理工作。您希望在调用delete()
时进行额外的清理,即使这是来自父类。
答案 1 :(得分:0)
F.f但是F.f不是叫F.g,而是叫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();}
答案 2 :(得分:0)
当您覆盖某个方法时,无论您从哪里调用它,都会始终使用被覆盖的版本。
当您在基类中执行this.g()
,并且当前对象属于子类时,您在子类中调用g()
。
如果基类中有从基类调用的任何方法,并且您不希望它们被派生类替换,那么您应该将该方法设置为private和final。
答案 3 :(得分:0)
您的Fbis
课程会覆盖方法g()
。如果您创建Fbis
的新对象,则g
中唯一的方法是Fbis
中定义的方法。即使你从一个继承的方法中调用它,它仍然是唯一的一个。否则,如果你创建一个Fbis
对象this
指向该对象,也就是说它是否在超类中使用。
答案 4 :(得分:0)
因为你正在“覆盖”Fbis中的方法g()。了解只使用“super.g”将保留覆盖。
答案 5 :(得分:0)
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
}