访问父类字段“ this.field”与“ super.field”

时间:2019-02-14 12:19:14

标签: java inheritance field

我想知道使用thissuper访问父类字段之间的区别。

我们有以下名为ListItem的抽象类,它扩展了Node类。

public abstract class ListItem {
        protected ListItem rightLink=null;
        abstract ListItem next();
    }

以及Node类中的以下代码:

public class Node extends ListItem {
@Override
    ListItem next() {
        return this.rightLink;
    }

但是,如果我们使用代码super.rightLink,则在编译时或运行时不会出现任何错误。我只想知道两者之间有什么区别,是否有最佳实践来完成任务?

2 个答案:

答案 0 :(得分:6)

说明

在这种情况下没有关系,

该字段在父类中声明。因此从技术上讲super.rightLink是最有意义的。但是,superthis仅与解决具有可变阴影的模糊情况有关。

在这种情况下,最好的做法是省略任何前缀,而只需键入rightLink。但这有点基于意见。


示例

假设我们有以下内容

public class Parent {
    int variable = 1; // Field
}

public class Child extends Parent {
    int variable = 2; // Field

    public void foo() {
        int variable = 3; // Local variable

        System.out.println(variable); // 3
        System.out.println(this.variable); // 2
        System.out.println(super.variable); // 1
    }
}

深入

因此,我们有一个情况,其中包含3个不同的变量,它们都位于不同的作用域中,但是它们具有相同的名称。当您仅键入variable时,Java将引用作用域最小的变量。这将是方法中的局部变量。 如果要访问您的字段,则需要执行this.variable。如果要访问父母的字段,则需要执行super.variable

同样,我们在这里有三个不同的变量。

  • 无前缀:最小范围
  • this:范围最小的字段
  • super:范围最小的字段,从直接父级开始

但是,在您的特定示例中,我们根本没有名称隐藏。名称为rightLink的变量只有一个。因此,这三个变体均指的是完全相同的变量。

在这种情况下,最好的做法是根本不使用前缀,只需使用rightLink


JLS

让我们看看Java语言规范如何定义this.super.

对于this.,请参考JLS§15.8.3

  

用作主要表达式时,关键字this表示一个值,该值是对该对象的引用(为此调用实例方法或默认方法(§15.12 )或要构造的对象。在lambda主体中此表示的值与周围上下文中此表示的值相同。

对于super.,请参考JLS§15.11.2

  

表单super.Identifier指代当前对象的名为Identifier的字段,但是 current 对象被视为该对象的实例当前课程的超类

答案 1 :(得分:1)

除非将rightLink标记为私有,否则在ListItem派生的所有类中都可以访问它。因此,呼叫super.rightLingthis.rightLink将是等效的。

通常,super是指基类,而this是指您所在的类。请适当地使用它们。

通常在覆盖方法时使用,即

@Override
public void DoSomething(){
  // Execute base imlpementation of a method
  super.DoSomething();
  // some additional code to add extra functionality to base class
}