简体   繁体   English

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

[英]Difference between super and this in the commands below?

What is the difference between these commands when I have a class A and a Class B where B extends A , and they have a common instance variable size and the commands below are called from a method printSize1 inside B? 当我拥有A类和B扩展了A的B类并且它们具有公共实例变量大小并且下面的命令从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);
    }
}

Also I have the same question with these two. 我对这两个也有同样的问题。 I have a class A and a class B where B extends A, and they both have a method with the same name printSize and an instance variable size and the below commands are called from a method printSize2 inside class B. 我有一个类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);
    }
}

i have a class A and a Class B where B extends A which they have a common instance variable size 我有一个A类和一个B类,其中B扩展了A,它们具有相同的实例变量大小

No, they don't. 不,他们没有。 They have separate instance variables called size . 它们具有称为size 单独的实例变量。 One is in the part of the object associated with A, and the other is in the part of the object associated with B. Let's call them A$size and B$size . 一个位于与A关联的对象的一部分中,另一个位于与B关联的对象的一部分中。我们将它们称为A$sizeB$size For them to have a common instance variable, you'd remove the declaration of size from B so they're both using A$size . 为了使它们具有公共实例变量,您可以从B删除size的声明,以便它们都使用A$size

Redeclaring an ancestor's non- private instance variable (field) is always a bad idea, because it leads to this sort of confusion. 重新声明祖先的非private实例变量(字段)总是一个坏主意,因为这会导致这种混乱。

Both of the below output 0 for your example code, because they're both accessing A$size , which you never assign a value to, so it has the default value 0 : 以下两个示例代码的输出均为0 ,因为它们都访问A$size ,而您从未为其分配值,因此它的默认值为0

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

So the question is: Why are they both using A$size and not B$size ? 所以问题是: 为什么他们都使用A$size而不使用B$size Because of the type of the reference we're using to look up size . 由于引用的类型 ,我们用来查找size In both cases, the type of the reference is A , because the type of (A)this is A (via cast) and the type of super in a method in B is also A . 在这两种情况下,引用的类型都是A ,因为(A)this的类型是A (通过强制转换),并且B中方法的super的类型也是A Since the type of the reference is A , it's A 's size that gets used. 由于引用的类型为A ,因此将使用Asize

In this particular case there isn't much of a difference between the two, but there would be if you added another layer to the hierarchy: 在这种特殊情况下,两者之间没有太大的区别,但是如果您向层次结构中添加了另一层,那就会有很大的区别:

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
    }
}

Moral of the story: Don't redeclare instance variables declared by an ancestor (unless the ancestor's version is private ). 故事的寓意:不要重新声明由祖先声明的实例变量(除非祖先的版本是private )。

Note that this is different for variables than it is for methods. 请注意,这是不同的变量比它的方法。 Instance methods are polymorphic. 实例方法是多态的。 Instance variables are not. 实例变量不是。 With methods, you get the method associated with the final type of the object (unless you use super or a qualified super , because those are special and bypass polymorphism). 使用方法,您可以获得与对象的最终类型关联的方法(除非您使用super或qualified super ,因为它们是特殊的并且绕过了多态性)。

This is what's coming into play in your second example in printSize2 . 这就是您在printSize2的第二个示例中所printSize2 Because methods are polymorphic, it doesn't matter that you've cast this to be type A in ((A)this).printSize() , you still get B 's printSize . 因为方法是多态的,没关系,你已经投this将是类型A((A)this).printSize()你仍然可以得到BprintSize But super.printSize() is special because super is special and bypasses polymorphism, giving B access to A 's printSize . 但是super.printSize()是特殊的,因为super是特殊的并且绕过了多态性,从而使B可以访问AprintSize

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM