问题
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