在下面的命令中super和this之间的区别?

时间:2017-03-18 15:45:09

标签: java this super

当我有A类和B类时,这些命令有什么区别,其中B扩展A,并且它们有一个公共实例变量 size ,下面的命令是从方法中调用的< B>

中强> printSize1
class A {
    protected int size;
}

class B extends A {
    protected int size=7; 

    public void printSize1() {
        System.out.println(((A)this).size)
        System.out.println(super.size);
    }
}

我对这两个问题也有同样的疑问。我有一个A类和一个B类,其中B扩展了A,它们都有一个同名的方法 printSize 和一个实例变量 size ,下面的命令被调用来自B类中的方法 printSize2

class A {
    protected int size;

    public void printSize() {
        System.out.println("Size=" + size);
    }
}

class B extends A {
    protected int size=7;

    public void printSize2 {
        ((A) this).printSize();
        super.printSize();
    }

    public void printSize() {
       System.out.println ("MSize="+size);
    }
}

1 个答案:

答案 0 :(得分:2)

  

我有一个A类和一个B类,其中B延伸A,它们有一个共同的实例变量 size

不,他们没有。他们有单独的实例变量名为size。一个是与A关联的对象的一部分,另一个是与B关联的对象的一部分。让我们称它们为A$sizeB$size。要让他们拥有通用实例变量,您需要从size删除B的声明,以便他们都使用A$size

重新声明祖先的非private实例变量(字段)总是一个坏主意,因为它会导致这种混淆。

以下两个输出0代表您的示例代码,因为它们都访问A$size,您从未为其分配值,因此它具有默认值0

System.out.println(((A)this).size);  // 0
System.out.println(super.size);      // 0

所以问题是:为什么他们都使用A$size而不是B$size?由于我们用于查找size的引用的类型。在这两种情况下,引用的类型都是A,因为(A)this的类型为A(通过强制转换),super的类型为B 1}}也是A。由于引用的类型为A,因此A的{​​{1}}被使用。

在这个特定的情况下,两者之间没有太大的区别,但是如果你在层次结构中添加了另一个层,那就是:

size

故事的道德:不要重新声明祖先声明的实例变量(除非祖先的版本是class A { protected int size = 1; } class B extends A { protected int size = 2; } class C extends B { protected int size = 3; void printSize() { System.out.println(((A)this).size); // 1 System.out.println(super.size); // 2 System.out.println(this.size); // 3 } } )。

请注意,对于变量而言,这与方法的不同。实例方法是多态的。实例变量不是。使用方法,您可以获得与对象的最终类型相关联的方法(除非您使用private或限定的super,因为这些是特殊的并绕过多态)。

这是super中第二个例子中的内容。因为方法是多态的,所以在printSize2中将this转换为A类型并不重要,您仍然可以获得((A)this).printSize()的{​​{1}} 。但B是特殊的,因为printSize是特殊的,绕过多态,让super.printSize()访问super的{​​{1}}。