简体   繁体   English

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

[英]Access to superclass private fields using the super keyword in a subclass

For a coding project I have a class containing a nested class. 对于编码项目,我有一个包含嵌套类的类。 The nested class is subclassed within the same outer class. 嵌套类在同一外部类中进行子类化。 The intention is for the outer class to contain some instances of the nested class which it can hand to other instances of the outer class. 目的是让外部类包含嵌套类的一些实例,它可以将其交给外部类的其他实例。

The nested subclass allows the outer class to modify the contents while its superclass allowes the contents to be read and some methods invoked. 嵌套子类允许外部类修改内容,而其超类允许读取内容并调用某些方法。 The superclass objects are thus handed to other objects to links the outer class objects in a chain. 因此,超类对象被传递给其他对象以链接链中的外部类对象。

The question I have concerns the access modifiers. 我的问题涉及访问修饰符。 Here is a minimalist code example: 这是一个极简主义的代码示例:

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;
        }
    }
}

When looking up some documentation I was confused by the ability to access the private field of the superclass not being mentioned anywhere. 在查找某些文档时,我对访问超类的私有字段的能力感到困惑,这些字段在任何地方都没有提到。 Is there any resource explaining why the subclass is allowed to modify the private field of the superclass in this way? 是否有任何资源解释为什么允许子类以这种方式修改超类的私有字段?

I am completely fine with this working. 这项工作我完全没事。 I also noticed that it seems to work with data being marked as protected instead of private and not using the super keyword. 我还注意到它似乎与数据被标记为受保护而不是私有而不使用超级关键字。 I am mostly interested in any documentation mentioning this ability of the super keyword. 我最感兴趣的是提到super关键字的这种能力的任何文档。 Thanks in advance. 提前致谢。

According to the Java Language Specification 根据Java语言规范

Example 6.6-5. 例6.6-5。 Access to private Fields, Methods, and Constructors 访问私有字段,方法和构造函数

A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. 私有类成员或构造函数只能在顶级类(第7.6节)的主体内访问,该类包含成员或构造函数的声明。 It is not inherited by subclasses. 它不是由子类继承的。

So what happens is the inner class can see a non-private field directly since it inherits it. 所以会发生什么是内部类可以直接看到非私有字段,因为它继承了它。

However, for private fields the inner class has to use super.field to access it since it is not inherited (otherwise you get a compiler error " field is not visible"). 但是,对于私有字段,内部类必须使用super.field来访问它,因为它不是继承的(否则会出现编译器错误“ field不可见”)。 Even though it is not inherited it is still accessible because the inner class is inside the outer class and private fields are accessible to anything inside the body of the top level class. 即使它不是继承的,它仍然是可访问的,因为内部类在外部类中,并且私有字段可以被顶级类主体内的任何内容访问。

What You Can Do in a Subclass 您可以在子类中执行的操作

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent. 子类继承其父类的所有公共成员和受保护成员,无论子类在哪个包中。如果子类与其父类在同一个包中,它还继承父类的包私有成员。 You can use the inherited members as is, replace them, hide them, or supplement them with new members: 您可以按原样使用继承的成员,替换它们,隐藏它们或用新成员补充它们:

The inherited fields can be used directly, just like any other fields. 继承的字段可以直接使用,就像任何其他字段一样。 You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended). 您可以在子类中声明一个与超类中的字段同名的字段,从而隐藏它(不推荐)。 You can declare new fields in the subclass that are not in the superclass. 您可以在子类中声明不在超类中的新字段。 The inherited methods can be used directly as they are. 继承的方法可以直接使用。 You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it. 您可以在子类中编写一个新实例方法,该方法与超类中的签名具有相同的签名,从而覆盖它。 You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it. 您可以在子类中编写一个新的静态方法,该方法与超类中的签名具有相同的签名,从而隐藏它。 You can declare new methods in the subclass that are not in the superclass. 您可以在子类中声明不在超类中的新方法。 You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super. 您可以编写一个子类构造函数,它可以隐式地或使用关键字super来调用超类的构造函数。 The following sections in this lesson will expand on these topics. 本课程的以下部分将扩展这些主题。

Private Members in a Superclass 超级私人会员

A subclass does not inherit the private members of its parent class. 子类不继承其父类的私有成员。 However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass. 但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

A nested class has access to all the private members of its enclosing class—both fields and methods. 嵌套类可以访问其封闭类的所有私有成员 - 包括字段和方法。 Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass. 因此,子类继承的公共或受保护嵌套类可以间接访问超类的所有私有成员。

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

JLS §6.6.1. JLS§6.6.1。 Determining Accessibility (emphasis mine): 确定可访问性 (强调我的):

A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access: 只有在类型可访问且声明成员或构造函数允许访问时,才能访问引用类型的成员(类,接口,字段或方法)或类类型的构造函数:

[...] [...]

Otherwise, the member or constructor is declared private, and access is permitted if and only if it occurs within the body of the top level class that encloses the declaration of the member or constructor. 否则,成员或构造函数被声明为private,并且当且仅当它发生在包含成员或构造函数声明的顶级类的主体内时才允许访问。

That simply means you can access all private members as long as you access them from within your top level type. 这只是意味着只要您从顶级类型中访问它们,就可以访问所有私有成员。

The super keyword is not needed for determining accessibility. 确定可访问性不需要super关键字。 It also works without. 它也没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用setter的情况下从子类访问父类中的私有字段? - How to access private fields in superclass from a subclass without using setters? 在子类中访问超类的私有字段 - Accessing Private Fields Of Superclass in SubClass 使用super关键字从子类访问超类成员 - Accessing superclass members from subclass with super keyword 在子类的方法中本地调用超类方法时,使用“ super”关键字还是使用超类实例? - Using “super” keyword or using a superclass instance when calling superclass methods locally in a method from subclass? 在子类中使用“this”/“super”都给出了超类的字段,但在子类构造函数中只允许使用“super” - Using "this"/"super" in the subclass both give superclass's fields but only "super" is allowed in subclass constructor 访问超类中子类的受保护字段? - Access protected fields of a subclass in a superclass? 如何在运行时使用超类实例访问子类字段 - How to access subclass fields at runtime using superclass instance 如何使用多态性访问未在超 class 中使用超类的引用变量定义的子类中的方法 - How to use polymorphism to access a method inside a subclass that is not defined in the super class using a reference variable of a superclass 超级关键字是否应该访问私有字段和方法。 我可以访问私有方法和字段 - Should super keyword get access to private fields and methods. I am able to get access to private methods and fields 用这个。 或超级。 调用存在于超类和子类中的方法时 - Using this. or super. when calling a method that exist in a superclass and a subclass
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM