有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在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()应该调用属于类TreAf(),但是x呢?我从未实例化过TreA。为什么它使用属于TreBx?这个案子的范围是什么


共 (3) 个答案

  1. # 1 楼答案

    无论何时从任何地方调用该类,该变量都会自身实例化。 调用默认构造函数并设置变量的值

    你可以看到这个例子。变量值是在调用该类时设置的

    public class TreA {
        int x = 1;
        public static void main(String[] a){
            TreA b = new TreA();
           System.out.println(b.x);
        }
    }
    

    输出为1

  2. # 2 楼答案

    扩展类意味着子类包含父类中的所有内容

    I'll overwrite it's f() method and get a copy of int x=1

    你没有得到一份拷贝,你只是拥有它(你继承了它)并且可以使用它

    无论您在何处使用x,它始终是从TreA继承的同一个变量,因此当TreA.f()修改它时,它正在修改您拥有的x的唯一实例

    I have never instantiated TreA

    创建子类意味着您也在创建父类。当您创建子类时,会自动调用其构造函数

    您必须这样思考TreB固有的包含TreA,然后您可以向其中添加内容并进行覆盖

    为了更好地了解情况,这是您的A级课程:

    parent class

    这是它的子类B:

    child class

    正如您所看到的,B中的x变量是A类中的变量,而不是副本

  3. # 3 楼答案

    当您实例化TreB时,将构造一个TreA(更具体地说,这是一个TreB)。TreB没有向TreA隐藏字段的字段x,因此该对象只有一个字段x,在TreA中定义。您可以从TreB访问它,因为您没有将其声明为私有

    顺便说一句,这是一种不好的做法,非最终字段应该始终是私有的,以避免类似的问题。使用getter从TreA获取用于TreB的值