7

当我浏览这篇文章时,在超类中的私有成员部分下,我看到了这一行

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

我的问题是我们如何直接访问inNested类(就像我们可以访问任何,字段一样)?BaseDerivedpublicprotected

如果有办法,如何Derived访问throughp的私有字段?BaseNested

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' ?
    }

}

提前感谢您在此线程中花费的时间和精力!

4

3 回答 3

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

或者对于派生类,这应该有效:

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

我不确定您是否需要使用 super 关键字

于 2013-07-17T18:06:14.897 回答
2

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

Nested nested = new Nested();

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

因为内部类是公共的,在 Base 或 Derived 之外定义的代码也可以创建实例。但这需要 Derived 或 Base 的封闭实例。Java 对此有特殊的语法,您可以在封闭类的实例上调用 new 运算符。因此,在 Base 或 Derived 之外,您可以执行以下操作:

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 但不需要封闭实例的类,您也可以使用静态嵌套类。

于 2015-05-26T08:32:49.770 回答
0

你可能知道,Nested只有当有一个包含Nested类定义的类的封闭实例时才能创建,在我们的例子中是Enclosing类。为了能够Enclosing通过继承类来访问类的私有成员Nested,我们需要向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();
    }
}
于 2017-11-11T10:49:36.223 回答