[英]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.