使用子类中的super关键字访问超类私有字段

时间:2015-07-17 14:55:38

标签: java class inheritance

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

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

我遇到的问题是访问修饰符。这是一个极简主义的代码示例:

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关键字的这种能力的任何文档。提前谢谢。

3 个答案:

答案 0 :(得分:9)

根据Java Language Specification

  

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

     

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

所以会发生什么是内部类可以直接看到非私有字段,因为它继承了它。

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

答案 1 :(得分:2)

您可以在子类中执行的操作

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

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

超类中的私人会员

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

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

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

答案 2 :(得分:0)

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

  

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

     

[...]

     

否则,成员或构造函数被声明为private,当且仅当它出现在包含成员或构造函数的声明的顶级类的主体内时才允许访问

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

确定辅助功能不需要super关键字。它也可以不用。