在Java中扩展类时重写方法重载
如果我有此代码:
interface Tre{
public void f();
}
public class TreA implements Tre{
int x = 1;
public void f(){
x++;
System.out.println("Y"+x);
}
public static void main(String[] a){
Tre a3 = new TreB(); a3.f();
}
}
class TreB extends TreA{
public void f(){
x--;
super.f();
System.out.println("X"+x);}
}
我不明白为什么输出是Y1 X1
。如果我扩展类TreA
,我将覆盖它的f()
方法并获取int x=1
的副本。调用super.f()
应该调用属于类TreA
的f()
,但是x
呢?我从未实例化过TreA
。为什么它使用属于TreB
的x
?这个案子的范围是什么
# 1 楼答案
无论何时从任何地方调用该类,该变量都会自身实例化。 调用默认构造函数并设置变量的值
你可以看到这个例子。变量值是在调用该类时设置的
输出为
1
# 2 楼答案
扩展类意味着子类包含父类中的所有内容
你没有得到一份拷贝,你只是拥有它(你继承了它)并且可以使用它
无论您在何处使用
x
,它始终是从TreA
继承的同一个变量,因此当TreA.f()
修改它时,它正在修改您拥有的x
的唯一实例创建子类意味着您也在创建父类。当您创建子类时,会自动调用其构造函数
您必须这样思考
TreB
固有的包含TreA
,然后您可以向其中添加内容并进行覆盖为了更好地了解情况,这是您的A级课程:
这是它的子类B:
正如您所看到的,B中的
x
变量是A类中的变量,而不是副本# 3 楼答案
当您实例化TreB时,将构造一个TreA(更具体地说,这是一个TreB)。TreB没有向TreA隐藏字段的字段x,因此该对象只有一个字段x,在TreA中定义。您可以从TreB访问它,因为您没有将其声明为私有
顺便说一句,这是一种不好的做法,非最终字段应该始终是私有的,以避免类似的问题。使用getter从TreA获取用于TreB的值