2013-07-17 70 views
4

当我经历this文章,下部分私有成员在一个超,我看到了这条线继承的嵌套类到子类

嵌套类访问其封闭的所有私有成员 类 - 这两个字段和方法。因此,由子类继承的公共或受保护的嵌套类可间接访问超类的所有私有成员。

我的问题是我们如何能够直接访问NestedBaseDerived(就像我们可以访问任何publicprotected领域)?

如果有一种方法,怎么能Derived访问p这是Base私人领域通过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' ? 
    } 

} 

在此感谢您的时间和精力!

回答

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

或者派生类,这应该工作:

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

我不知道,如果你需要使用super关键字或不

+3

注意'Nested'取决于'实例Base',这就是为什么'Nested'的一个实例可以访问'Base'的东西。 'Base'实例化隐含在'new Base.Nested()'上。 I. e。你可以这样写: 'Base myBase = new Base(); Base.Nested theClassBro = myBase.new嵌套();' –

1

非静态内部类总是需要一个嵌套类的封闭实例。在Base Base或Derived类中定义的代码(因为它继承了内部类),您可以简单地编写

Nested nested = new Nested(); 

创建一个新实例。然后,您可以调用Nested引用上的getP()方法来获取私有p值的值。该值是封装了Nested实例的Base类实例的一部分。

因为内部类是公共的,所以在Base或Derived之外定义的代码也可以创建一个实例。但是这需要一个Derived或Base的封闭实例。对于这种情况,Java在包含类的实例上调用new运算符时有特殊的语法。因此,基地外或派生,你可以这样做:

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

它也可以导入Base.Nested,这样你可以写:

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

这是很好的了解这个语法,但我觉得代码如果只允许封闭类创建内部类的新实例,它通常更清晰(更容易理解,更好的封装)。如果您需要一个逻辑上仅属于Base但不需要封闭实例的类,则还可以使用静态嵌套类。

0

如您所知,Nested只能在包含Nested类定义的类的封闭实例时创建,在我们的例子中为Enclosing类。为了能够通过继承Nested类来访问Enclosing类的私有成员,我们需要向Derived类的构造函数提供包含Enclosing.Nested的封闭实例。下面的代码应该让它更清楚地理解。我从你原来的例子改变的变量和类的名称为更好地理解:


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