Kiv*_*Kiv 17 java inner-classes
我很难在Java中围绕非静态嵌套类.请考虑以下示例,其中打印"内部",然后打印"子".
class Outer {
class Inner {
Inner() { System.out.println("Inner"); }
}
}
public class Child extends Outer.Inner {
Child(Outer o) {
o.super();
System.out.println("Child");
}
public static void main(String args[]) {
new Child(new Outer());
}
}
Run Code Online (Sandbox Code Playgroud)
我理解Inner的实例总是必须与外部实例相关联,并且这也适用于Child,因为它扩展了Inner.我的问题是o.super()语法的含义 - 为什么它会调用Inner构造函数?
我只看到一个普通的super(args)用于调用超类构造函数并super.method()调用重写方法的超类版本,但从来没有形式的东西instance.super().
Art*_*cto 11
它被称为"合格的超类构造函数调用".
引自这里:
显式构造函数调用语句可以分为两种:
替代构造函数调用以关键字this开头(可能以显式类型参数开头).它们用于调用同一类的备用构造函数.
超类构造函数调用以关键字super(可能以显式类型参数开头)或Primary表达式开头.它们用于调用直接超类的构造函数.超类构造函数调用可以进一步细分:
非限定超类构造函数调用以关键字super开头(可能以显式类型参数开头).
合格的超类构造函数调用以Primary表达式开头.它们允许子类构造函数显式指定新创建的对象关于直接超类(第8.1.3节)的直接封闭实例.当超类是内部类时,这可能是必要的.
Gun*_*r47 10
内部类(非静态子类)本质上是嵌套类(静态子类),其隐式链接返回其父对象.以下是您使用静态嵌套类编写的上述代码:
class Outer {
static class Inner {
final Outer outer;
Inner(Outer outer) {
this.outer = outer;
System.out.println("Inner");
}
}
}
public class Child extends Outer.Inner {
Child(Outer o) {
super(o); // o.super();
System.out.println("Child");
}
public static void main(String args[]) {
new Child(new Outer());
}
}Run Code Online (Sandbox Code Playgroud)
看看这个,你应该能够理解o.super()正在做什么.
为什么o.super()在Child结束了调用Outer.Inner构造函数?这很简单:因为Child extends Outer.Inner构造函数调用总是链接到层次结构中.
以下是对您的代码段的轻微扩展,以说明:
class Outer {
Outer() {
System.out.println("Outer");
}
void outerMethod() { }
class Inner {
Inner() {
System.out.println("OuterInner");
outerMethod();
}
String wealth;
}
}
class OuterChild extends Outer {
OuterChild() {
System.out.println("OuterChild");
}
}
public class OuterInnerChild extends Outer.Inner {
OuterInnerChild(Outer o) {
o.super();
System.out.println("OuterInnerChild");
this.wealth = "ONE MILLION DOLLAR!!!";
}
public static void main(String args[]) {
System.out.println(new OuterInnerChild(new Outer()).wealth);
new OuterChild();
}
}
Run Code Online (Sandbox Code Playgroud)
这打印:
Outer
OuterInner
OuterInnerChild
ONE MILLION DOLLAR!!!
Outer
OuterChild
Run Code Online (Sandbox Code Playgroud)
一些重要观察:
OuterInnerChild extends Outer.Inner,它继承wealth,就像普通的子类语义一样
OuterInnerChild链的构造函数也是构造函数的Outer.InnerOuterChild extends Outer,它的构造函数链,即使没有显式调用
但是为什么编译器要求
OuterInnerChild构造函数接受一个Outer o,并且o.super()调用它?
现在这是特定于内部类语义的:它是为了确保所有实例OuterInnerChild都有一个封闭的Outer实例Outer.Inner,超类OuterInnerChild.否则,构造函数Outer.Inner将没有Outer要调用的封闭实例outerMethod().