Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1800704
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: Java

2012-03-25 21:58:17

Java的内部类很有趣。你可以这样定义一个内部类:


  1. class Outer {
  2.     class Inner {}
  3. }

Inner是必须与某一个Outer对象绑定的,通过外部创建内部类的方法就可以得知:


  1. Outer oo = new Outer();
  2. Outer::Inner ii = oo.new Inner();

所以每一个Inner都有对应的一个外部类对象,而且内部类可以访问外部类对象中的所有属性和方法,包括private权限的。内部类可以用Outer.this来得到外部类对象的引用:


  1. class Outer {
  2.     class Inner {
  3.         Outer GetOuter()
  4.         {
  5.             return Outer.this;
  6.         }
  7.     }
  8. }

在方法中或一个作用域“{}”中也可以定义内部类,用一段比较变态的代码来说明问题:


  1. class Outer {
  2.     int a = 6
  3.     class Inner {
  4.         int b = 3;
  5.         void f()
  6.         {
  7.             class FunInner { // class defined in a funciton!!
  8.                 int sum()
  9.                 {
  10.                     return a + b; // Outer.a + Inner.b
  11.                 }
  12.             }
  13.             FunInner fi = new FunInner();
  14.             System.out.print(fi.sum()); // 9!!
  15.         }
  16.     }
  17. }

还有一种东西叫“匿名内部类”:


  1. interface I {
  2.     void f();
  3. }

  4. class Outer {
  5.     I getI()
  6.     {
  7.         return new I() { // anonymous inner class !!
  8.             public void f() {}
  9.         };
  10.     }
  11. }

如果不需要和外部类绑定,可以定义一个嵌套类


  1. class Outer {
  2.     static class Nested {} // static
  3. }

嵌套类和C++中的嵌套类基本相同,只能访问外部类的静态数据。它的创建方法为:


  1. Outer.Nested nested = new Outer.Nested();

接口里面也可以定义嵌套类,但不需要static修饰,因为接口里定义的变量都是默认为public static的:


  1. interface I {
  2.     void f();
  3.     class MyI implements I {
  4.         void void f() {}
  5.     }
  6. }

这样做的好处是接口的定义同时还能提供默认的实现。

内部类的作用:
内部类可以继承别的类,同时又可以完全访问外部类的成员,这就等同于多重继承的效果。
Java里没有指针,所以不能像C++一样把函数指针传递给出去作为回调函数(callback)。通过内部类可以实现:


  1. interface Callback { void call(); }

  2. class MyClass {
  3.     void f() {} // want to be a callback
  4.     Callback getCallback()
  5.     {
  6.         return new Callback() {
  7.             void call() { f(); }
  8.         };
  9.     }
  10. }

  11. class Caller {
  12.     void operation(Callback callback)
  13.     {
  14.         callback.call();
  15.     }

  16.     static void main(String[] args)
  17.     {
  18.         Caller caller = new Caller();
  19.         MyClass mc = new MyClass();
  20.         caller.operation(mc.getCallback());
  21.     }
  22. }

Java中的这样的回调机制叫做闭包(closure)


内部类也可以被继承。因为外部类和内部类有着千丝万缕的联系,所以继承的类同样需要某种机制建立起这种联系: 


  1. class Outer { class Inner{} }
  2. public class InheritInner extends Outer.Inner {
  3.     // InheritInner() {} // compile error!
  4.     InheritInner(Outer oo) {
  5.         oo.super(); // It's a must to connect to the outer class
  6.     }
  7.     static void main(String[] args)
  8.     {
  9.         Outer oo = new Outer();
  10.         InheritInner ii = new InheritInner(oo);
  11.     }
  12. }


内部类同样会生成.class文件,它的文件名会是这样的形式:Outer$Inner.class。如果是匿名内部类,在$后会简单加入一个数字作为标识符。

阅读(828) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~