有 Java 编程相关的问题?

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

Java继承混乱,超类和子类成员变量同名

在运行此代码时

class c1 { int ci = 1; }

class c2 extends c1 { int ci = 2; }

class inheritanceTest {
    public static void main(String args[]) {
        c1 c1reftoc2 = new c2();
        System.out.println(c1reftoc2.ci);
    }
}

输出为1。所以我猜一个带有超类引用变量的子类对象,在两个类中的变量名称相同的情况下使用超类变量

但是,从一个SCJP问题运行这个程序

class Foo {
    public int a = 3;
    public void addFive() {
        a += 5;
        System.out.print("f ");
    }
}

class Bar extends Foo {
    public int a = 8;
    public void addFive() {
        System.out.println(this.a);
        this.a += 5;
        System.out.print("b " );
        System.out.println(this.a);
    }
}

class SCJPQC3 {
    public static void main(String[] args) {
        Foo f = new Bar();
        f.addFive();
        System.out.println(f.a);
    }
}

输出为

8
b 13
3

由于重写,在main()中调用的addFive()方法将是类Bar的方法

在{}中{}打印{}。而main()中的f.a给出了3。由this.f.引用的实例是相同的,但它们给出不同的结果。使用this.a8作为输出,这与我之前的理解相矛盾

所以我的问题是,this.指的是类还是实例?我知道this.会引用调用方法的对象,但这个特定的程序让我感到困惑


共 (2) 个答案

  1. # 1 楼答案

    当在子类中用与超类中相同的名称声明变量时,与被覆盖的方法不同,您是在隐藏变量。这个区别是因为f指向一个Bar类型的对象,所以使用了Bar中的addFive()方法。然而,当调用f.a时,它的引用类型是Foo,它首先在那里寻找变量。因此,通常应避免在子类中隐藏变量

  2. # 2 楼答案

    这里的关键字this指的是调用方法的当前对象实例。由于多态性,调用了BaraddFive方法。该方法引用了那里作用域中的a,即Bara。(Bara隐藏了Fooa。)这就是8最初打印的原因,也是它更改为13的原因。然而,当在main的末尾调用System.out.println(f.a);时,编译器只将f视为Foo变量,因此它打印3{}{}的3变量,它从未从3更改