Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. Thanks in advance.

like image 413
Spearhead Avatar asked Jul 17 '15 14:07

Spearhead


2 Answers

According to the Java Language Specification

Example 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. 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"). 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.

like image 87
dkatzel Avatar answered Oct 05 '22 04:10

dkatzel


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. 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

like image 27
Pat B Avatar answered Oct 05 '22 05:10

Pat B