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

问题描述 投票:2回答:2

我想知道使用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,我在编译时或运行时都不会收到任何错误。我只是想知道两者之间有什么区别,是否有最佳实践来完成任务?

java inheritance field
2个回答
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)或正在构造的对象的引用。 λ体中由此表示的值与周围环境中由此表示的值相同。

对于super.,请参阅JLS§15.11.2

形式super.Identifier指的是当前对象的名为Identifier的字段,但当前对象被视为当前类的超类的实例。


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
}
© www.soinside.com 2019 - 2024. All rights reserved.