区分super和this

时间:2019-01-30 01:24:55

标签: java

我正在尝试为该语句寻找证据-关键字super是对父类的引用,就像关键字this是对当前类的引用一样。

我正在尝试使用Java A-> B-> C进行多级继承:类A是父级,类B是父级,类C是子级。

我在所有三个类中声明了一个变量X,它们的值分别为(A:x = 100,B:x = 200,C:x = 300)

在子类构造函数中,我正在打印值。但是,强制转换不适用于super关键字,而适用于this关键字。

((A)super).x无效,但是((A)this).x正常。

class A {
    int x = 100;
}

class B extends A {
    int x = 200;
}

public class C extends B {
    int x = 300;
    public C () {
        System.out.println(this.x); //OP = 300
        System.out.println(super.x); // OP = 200
        System.out.println(((A)this).x);// OP = 100
        System.out.println(((A)super).x); // Giving Compile time Error.. Why?
        B reftoB = new B();
        System.out.println(((A)reftoB).x);  // OP = 100
    }

    public static void main(String[] args) {
        C t1= new C();
    }
}

我希望System.out.println(((A)super).x)的输出为100,但它给出了编译时错误。

所以我的问题是,如果super是对父类的引用,那为什么不进行类型转换呢?

4 个答案:

答案 0 :(得分:4)

使用Super关键字:

  1. super()可用于引用直接父类实例 变量。
  2. super()可用于调用直接父类方法。
  3. super()可用于调用直接父类构造函数。

您的编译器是(A)super).x的编译错误,因为它不是有效的语句,而且我们不以这种方式使用它,在所有它违反封装的情况下,您应该无法绕过父类。在super()的每个定义中,您都会找到被称为当前父类的东西,但是您要在此处尝试做的是 绕过当前父类

现在遇到问题了:

x                // Field x in class C
this.x           // Field x in class C
super.x          // Field x in class B
((B)this).x      // Field x in class B
((A)this).x      // Field x in class A
super.super.x    // Illegal; does not refer to x in class A
((A)super).x     // Illegal as well as compilation error

如果您仍要访问想要的变量,请使用以下内容:

t1.x              // Field x of class C 
((B)t1).x         // Field x of class B
((A)t1).x         // Field x of class A

注意t1是您的C类实例。

答案 1 :(得分:1)

为什么可以this被强制转换而super不能回答answer的答案与为什么this可以作为方法参数但{{1 }}不能:也就是说,因为JLS将super定义为Primary Expression,而this却没有。

答案 2 :(得分:-1)

super关键字引用父类,而this关键字引用您所在的类。让我们创建一个父类以开始演示:

public class ParentClass{

  private int justANumber;

  public ParentClass(int justANumber){
    this.justANumber = justANumber;
  }

}

请注意,此处如何使用this关键字,它告诉“嘿,将justANumber值分配给也称为justANumber的THIS类属性”。现在,为该父类创建一个子类:

public class Subclass extends ParentClass{

  // You don't need to declare the justANumber variable, cause it's from the parent

  public Subclass(int justANumber){
    super(justANumber);
  }

  public showNumber(){
    return this.justANumber;
  }

}

super()方法将调用父构造方法,该方法首先需要一个int值,因此您将其作为参数传递。现在看看showNumber()方法如何返回this.justANumber吗?为什么?这是因为调用super()方法时,父类会自动将其变量委派给子类,因此,在这种情况下,Subclass可以说justANumber是HIS变量,能够使用this关键字。希望您现在了解不同之处。

答案 3 :(得分:-1)

首先,thissuper都没有引用“类”,它们都引用了作为类实例的对象。这不是挑剔的:这是我和人类之间的区别。

现在,当我执行new C(在原始帖子中的A-> B-> C层次结构中)时,我最终得到的正是一个对象,即使该对象具有A-ness,即B -ness和C-ness。因此,说superthis是对不同事物的引用是不合逻辑的;只有一件事。

因此,我们仅需得出结论,super是一种特殊的魔术,它可以绕过正常的覆盖分辨率规则。不遵循引用的正常行为也就不足为奇了。

这是不科学的答案;大概只需对语言规范进行一点挖掘就可以获得科学的答案。 ,,我发现的分页HTML格式不是特别可搜索。

编辑后添加:@ jaco0646表示了相关的参考-在JSE for Java SE 11的15.11.2节中。