【问题标题】:Access to superclass private fields using the super keyword in a subclass在子类中使用 super 关键字访问超类私有字段
【发布时间】:2015-10-07 08:17:50
【问题描述】:

对于一个编码项目,我有一个包含嵌套类的类。嵌套类是同一个外部类的子类。目的是让外部类包含嵌套类的一些实例,它可以将其交给外部类的其他实例。

嵌套的子类允许外部类修改内容,而其超类允许读取内容并调用一些方法。因此,超类对象被交给其他对象,以链式链接外部类对象。

我的问题与访问修饰符有关。这是一个极简代码示例:

abstract class OuterClass {


    protected class NestedSuperClass<T> {
        private T data;

        public NestedSuperClass (T t) {
            this.data = t;
        }

        public T getOutput() {
            return data;
        }
    }

    protected class NestedSubClass<T> extends NestedSuperClass<T> {
        public NestedSubClass (T t) {
            super(t);
        }

        protected void setOutput(T t) {
            super.data = t;
        }
    }
}

在查找一些文档时,我对访问超类的私有字段的能力感到困惑,但在任何地方都没有提到。是否有任何资源解释为什么允许子类以这种方式修改超类的私有字段?

我对这项工作完全满意。我还注意到,它似乎适用于标记为受保护而不是私有且不使用 super 关键字的数据。我最感兴趣的是任何提到 super 关键字的这种能力的文档。提前致谢。

【问题讨论】:

  • 我投票重新提出这个问题,因为它特别关注super 和私有字段访问而不是一般内部类可访问性的使用
  • 我也投票重新提出这个问题。它似乎与重复的问题无关。
  • 提示:合成编译器生成的访问器方法

标签: java class inheritance


【解决方案1】:

根据Java Language Specification

示例 6.6-5。访问私有字段、方法和构造函数

私有类成员或构造函数只能在包含成员或构造函数声明的顶级类(第 7.6 节)的主体内访问。它不被子类继承。

所以发生的事情是内部类可以直接看到一个非私有字段,因为它继承了它。

但是,对于私有字段,内部类必须使用super.field 来访问它,因为它不是继承的(否则会出现编译器错误“field 不可见”)。即使它没有被继承,它仍然可以访问,因为内部类在外部类内部,并且私有字段可以被顶级类的主体内的任何东西访问。

【讨论】:

    【解决方案2】:

    你可以在子类中做什么

    无论子类在哪个包中,子类都会继承其父类的所有公共和受保护成员。如果子类与其父类在同一个包中,它也会继承父类的包私有成员。您可以按原样使用继承的成员、替换它们、隐藏它们或用新成员补充它们:

    继承的字段可以直接使用,就像任何其他字段一样。 您可以在子类中声明一个与超类中同名的字段,从而隐藏它(不推荐)。 您可以在子类中声明不在超类中的新字段。 继承的方法可以直接使用。 您可以在子类中编写一个与超类具有相同签名的新实例方法,从而覆盖它。 您可以在子类中编写一个与超类具有相同签名的新静态方法,从而隐藏它。 您可以在子类中声明不在超类中的新方法。 您可以编写一个子类构造函数来调用超类的构造函数,可以隐式调用,也可以使用关键字 super。 本课的以下部分将扩展这些主题。

    超类中的私有成员

    子类不继承其父类的私有成员。但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

    嵌套类可以访问其封闭类的所有私有成员——包括字段和方法。因此,子类继承的公共或受保护的嵌套类可以间接访问超类的所有私有成员。

    参考: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

    【讨论】:

      【解决方案3】:

      JLS §6.6.1. Determining Accessibility(强调我的):

      引用类型的成员(类、接口、字段或方法)或类类型的构造函数,只有在类型可访问并且声明成员或构造函数允许访问时才可访问:

      [...]

      否则,成员或构造函数被声明为私有,并且允许访问当且仅当它发生在包含成员或构造函数声明的顶级类的主体内。 p>

      这仅仅意味着您可以访问所有私有成员,只要您从顶级类型中访问它们。

      确定可访问性不需要super 关键字。它也可以不使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 2018-09-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多