从零学java(14)——内部类(2)
26 March 2014
内部类分为两部分,实在因为有太多要写的。上一篇写了些内部类的基本用法,这一篇写一些关于为什么要用内部类。
Java花了这么大力气创造了内部类这个用法,必然有其重要性,那么内部类有什么好处呢?
之前也提到过,Java的类不能多重继承。那么我们想要多重继承,该怎么办?用接口啊,混蛋!多重继承搞什么,不用继承用组合!好吧,但是我偏要多重继承,终于内部类出场了。内部类的好处显而易见,一个内部类就是一个类,它爱继承什么继承什么,尤其是对于非接口。
package innerclasses;
class D {}
abstract class E {}
class Z extends D {
E makeE() { return new E() {}; }
}
public class MultiImplementation {
static void takesD(D d) {}
static void takesE(E e) {}
public static void main(String[] args) {
Z z = new Z();
takesD(z);
takesE(z.makeE());
}
}
啊,书中随后又举了两个例子——闭包与回调,内部类与控制框架。这两部分都有一些很长的代码和解释,在此就不多费口舌,大家感兴趣就查查书。
关于内部类的继承,比较复杂:
class WithInner {
class Inner {}
}
public class InheritInner extends WithInner.Inner {
//! InheritInner() {} // Won't compile
InheritInner(WithInner wi) {
wi.super();
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}
内部类可以被覆盖吗?呃。。为什么总是这么复杂的问题,又是继承又是覆盖。当某个类继承了某个外围类时,即使重新写了个内部类,这两个内部类也是完全独立的实体,各自在自己的命名空间内。如果一定要覆盖内部类,则需要明确地继承某个内部类:
class Egg2 {
protected class Yolk {
public Yolk() { print("Egg2.Yolk()"); }
public void f() { print("Egg2.Yolk.f()");}
}
private Yolk y = new Yolk();
public Egg2() { print("New Egg2()"); }
public void insertYolk(Yolk yy) { y = yy; }
public void g() { y.f(); }
}
public class BigEgg2 extends Egg2 {
public class Yolk extends Egg2.Yolk {
public Yolk() { print("BigEgg2.Yolk()"); }
public void f() { print("BigEgg2.Yolk.f()"); }
}
public BigEgg2() { insertYolk(new Yolk()); }
public static void main(String[] args) {
Egg2 e2 = new BigEgg2();
e2.g();
}
}
/* Output:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
*/
Java的内部类比较深奥,即使了解其特性也不容易写出优美的代码。这需要在不断实践中摸索,才知道在什么场合下使用才是适合的。
blog comments powered by Disqus