1 minute read

首先我们明确下 “enclose” 这个单词的逻辑关系:OuterClass encloses InnerClass,所以外部类就是 enclosing class,内部类是 enclosed class。


如果一个一般类来继承内部类,需要在构造器中使用特殊的语法。

class Outer {  
	class Inner {}  
}  
  
public class ExtInner extends Outer.Inner {  
	public ExtInner(Outer o) {  
		o.super();  
	}  
}  

ExtInner 的构造器必须要有一个 Outer 参数,然后调用 .super();。这里要求必须使用一个 enclosingClassReference.super();

题外话:你可能会问:在 ExtInner 的构造器里 return o.new Inner(); 行不行?编译器会告诉你:”constructor 的 return-type 是 void”。这个是本话题的意外收获。

然后 ExtInner 中无法通过 Outer.this 来连接到外部类对象,在 ExtInner 中使用 Outer.this 会得到编译错误 “Outer 不是封闭类” (Java SE 1.5.0_15),这里的封闭类应该就是 enclosing class 的意思,”Outer 不是封闭类” 表示 Outer 并没有 enclose ExtInner,虽然 Outer 有 enclose Inner,且 ExtInner 继承自 Inner

如果 Base 有一个 Inner,然后 Ext 继承了 Base,这时 Ext 并没有继承 Base.Inner 的代码,即 Base.Inner 的代码没有复制到 Ext 中。此时,如果在 Ext 中也写一个 Inner,其实是不会发生冲突的。


如果内部类、外部类双重继承,情况如何呢?看下面代码:

class BaseOuter {  
	void print() {  
		System.out.println("BaseOuter prints");  
	}  
	  
	class BaseInner {  
		void print2() {  
			System.out.println("BaseInner prints");  
		}  
		  
		void print3() {  
			BaseOuter.this.print();  
		}  
	}  
}  
  
class ExtOuter extends BaseOuter {  
	void print4() {  
		System.out.println("ExtOuter prints");  
	}  
	  
	class ExtInner extends BaseOuter.BaseInner {  
		void print5() {  
			System.out.println("ExtInner prints");  
		}  
		  
		void print6() {  
			ExtOuter.this.print4();  
		}  
		  
		void print7() {  
			BaseOuter.this.print(); // error: BaseOut is not the enclosing class  
		}  
	}  
}  
  
public class ExtInnerTest {  
	public static void main(String[] args) {  
		ExtOuter eo = new ExtOuter();  
		ExtOuter.ExtInner ei = eo.new ExtInner();  
		  
		ei.print2();  
		ei.print3();  
		ei.print5();  
		ei.print6();  
		ei.print7(); // error: BaseOut is not the enclosing class  
	}  
}  

可以看到 ExtInner 可以通过向上转型变成 BaseInner,然后再连接到 BaseOut.this (ei.print3(); // OK),但是不能直接使用 BaseOut.this (ei.print7(); // won't compile)。

总结一点,内部类不能被外部类的导出类继承,外部类也不 enclose 内部类的导出类。

Comments