Почему o.super()
in 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();
}
}
Это печатает:
Outer
OuterInner
OuterInnerChild
ONE MILLION DOLLAR!!!
Outer
OuterChild
Некоторые ключевые наблюдения:
- Поскольку
OuterInnerChild extends Outer.Inner
, он наследует wealth
, как и обычная семантика подкласса.
- И точно так же, как нормальная семантика подкласса, конструктор
OuterInnerChild
связывается с конструктором Outer.Inner
- Потому что
OuterChild extends Outer
, его конструктор цепочки, даже если не вызывается явно
- Неявно или явно, конструктор объединяет иерархию
Но почему компилятор требует, чтобы конструктор OuterInnerChild
занял Outer o
, и что o.super()
вызывается?
Теперь, что специфично для внутренней семантики класса: это сделано для того, чтобы все экземпляры OuterInnerChild
имели включающий Outer
экземпляр для Outer.Inner
, суперкласс OuterInnerChild
. В противном случае конструктор Outer.Inner
не будет иметь включающий экземпляр Outer
для вызова outerMethod()
on.