Inheriting Nested classes into Subclass

谁说我不能喝 提交于 2020-01-01 10:17:06

问题


When I was going through this article, under the section Private Members in a Superclass, i saw this line

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.

My question is how can we DIRECTLY access the Nested class of Base in Derived (like we can access any public, protected fields)?

and

if there is a way, how can Derived access p which is private field of Base through Nested?

public class Base {

    protected int f;
    private int p;

    public class Nested {

        public int getP() {
            return p;
        }
    }
}

class Derived extends Base {

    public void newMethod() {
        System.out.println(f); // i understand inheriting protected field

        // how to access the inherited Nested class here? and if accessed how to retrieve 'p' ?
    }

}

Thanks in advance for your time and effort in this thread!


回答1:


Base.Nested theClassBro= new Base.Nested();

Or for the Derived class, this should work:

Derived.Nested theClassBro= new Derived.Nested();

I'm not sure if you need to use the super keyword or not




回答2:


A non-static inner class always needs an enclosing instance of the class it is nested in. Within code defined in class Base or class Derived (because it inherits the inner class), you can simply write

Nested nested = new Nested();

To create a new instance. You can then invoke the getP() method on the Nested reference to get to the value of the private p value. This value is part of the instance of class Base that encloses the instance of Nested.

Because the inner class is public, code defined outside of Base or Derived can also create an instance. But this requires an enclosing instance of either Derived or Base. Java has special syntax for this where you invoke the new operator on an instance of the enclosing class. So outside of Base or Derived you can do:

Base base = new Base();
Base.Nested baseNested = base.new Nested();    
Derived derived = new Derived();
Derived.Nested derivedNested = derived.new Nested();
Base.Nested d = derivedNested;

It is also possible to import Base.Nested so that you can write:

Base base = new Base();
Nested baseNested = base.new Nested();
Derived derived = new Derived();
Nested derivedNested = derived.new Nested(); // Base.Nested reference

It's good to know this syntax, but I feel code is generally cleaner (easier to understand, better encapsulation) if only the enclosing class is allowed to create new instances of the inner class. You can also use a static nested class if you need a class that logically belongs only to Base but does not need an enclosing instance.




回答3:


As you may know, Nested can only be created when there is an enclosing instance of the class containing the Nested class definition, in our case it's the Enclosing class. To be able to access the private members of the Enclosing class through inheritance of its Nested class, we need to provide to the constructor of the Derived class, the enclosing instance that contains Enclosing.Nested. The following code should make it clearer to understand. I have changed the names of the variables and classes from your original example for better understanding:


public class Enclosing {

    protected int protectedMember = 3;
    private int privateMember = 7;

    public class Nested {

        public int getPrivate() {
            return privateMember;
        }

        public int getProtected() {
            return protectedMember;
        }

    }

}

class Derived extends Enclosing.Nested {

    //Provide the enclosing instance that contains Enclosing.Nested
    public Derived() {
        new Enclosing().super();
    }

    //Access protected member of Enclosing class
    public void accessProtectedMember() {
        System.out.println(getProtected());
    }

    //Access private Member of Enclosing class
    public void accessPrivateMember() {
        System.out.println(getPrivate());
    }

}

public class Test {
    public static void main(String... args) {
        Derived derived = new Derived();
        derived.accessProtectedMember();
        derived.accessPrivateMember();
    }
}


来源:https://stackoverflow.com/questions/17706978/inheriting-nested-classes-into-subclass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!