访问父类字段"this.field"VS"super.field"

Has*_*han 2 java inheritance field

我想知道使用this和访问父类字段之间的区别super.

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

public abstract class ListItem {
        protected ListItem rightLink=null;
        abstract ListItem next();
    }
Run Code Online (Sandbox Code Playgroud)

以及Node类中的以下代码:

public class Node extends ListItem {
@Override
    ListItem next() {
        return this.rightLink;
    }
Run Code Online (Sandbox Code Playgroud)

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

Zab*_*uza 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
    }
}
Run Code Online (Sandbox Code Playgroud)

深入

因此,我们有一个具有3个不同变量的情况,这些变量都存在于不同的范围内,但它们具有相同的名称.当您键入时variable,Java将引用具有最低范围的变量.哪个是方法中的局部变量.如果您想访问您的领域,您需要这样做this.variable.如果要访问父级字段,则需要执行此操作super.variable.

所以,我们在这里有三个不同的变量.

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

但是,在您的具体示例中,我们根本没有名称阴影.名称只有一个变量rightLink.所以这三个变体都指的是完全相同的变量.

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


JLS

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

有关this.,请参阅JLS§15.8.3:

当用作主表达式时,关键字this表示一个值,该值是调用实例方法或默认方法的对象(第15.12节)的引用,或者是对正在构造的对象的引用.λ体中由此表示的值与周围环境中由此表示的值相同.

有关super.,请参阅JLS§15.11.2:

表单super.Identifier引用Identifier当前对象命名的字段,但将当前对象视为当前类的超类的实例.