【问题标题】:differentiate between super and this [duplicate]区分超级和这个[重复]
【发布时间】:2019-06-23 05:33:26
【问题描述】:

我正在尝试为该声明找到证据 - 关键字 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 是对父类的引用,那么为什么类型转换不工作呢?

【问题讨论】:

  • 这只是无效的语法。 super 不能这样使用。它只能在直接字段访问/方法调用表达式中使用,而不会进行强制转换。
  • super 指的是与this 相同的实例。您尝试做的事情没有意义。
  • super 不是“对父类的引用”。它是一个关键字,允许您引用继承的字段或方法。仅此而已。

标签: java


【解决方案1】:

为什么this 可以被转换但super 不能被转换的答案与answer 为什么this 可以作为方法参数传递但super 不能被传递的问题相同:即,因为this JLS 将其定义为Primary Expression,但super 不是。

【讨论】:

  • 支持指向语言规范的(间接)指针; JLS for Java SE 11 中的第 15.11.2 节,供任何其他感兴趣的人使用。
【解决方案2】:

使用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 类实例。

【讨论】:

  • super()super 是完全不同的东西。前者是构造函数调用,后者操作是为了修改通常的名称解析算法。
【解决方案3】:

super关键字是类父类,this是你所在的类。让我们创建一个父类开始演示:

public class ParentClass{

  private int justANumber;

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

}

注意这里如何使用this 关键字,它告诉“嘿,将justANumber 值分配给这个类属性,也称为justANumber”。现在让我们为这个父类创建一个子类:

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关键字.希望您现在了解差异。

【讨论】:

  • 原帖没有在任何地方使用超类构造函数调用super()。它使用并询问超类访问关键字super
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 2014-07-27
  • 2014-05-28
  • 1970-01-01
  • 2010-12-27
  • 2011-05-19
  • 2021-09-16
相关资源
最近更新 更多