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