java 内部类详解(四)

2014-11-24 07:48:32 · 作者: · 浏览: 3
就可以这样做。当然,定义在方法中的内部类可以使设计多样化,用途绝不仅仅在这一点。

下面有一个更怪的例子:

Java代码 收藏代码
  1. public class Goods2{
  2.  private void internalTracking(boolean b) {
  3.   if(b) {
  4.    class TrackingSlip {
  5.     private String id;
  6.     TrackingSlip(String s) {
  7.      id = s;
  8.     }
  9.     String getSlip() { return id; }
  10.    }
  11.    TrackingSlip ts = new TrackingSlip("slip");
  12.    String s = ts.getSlip();
  13.   }
  14.  }
  15.  public void track() { internalTracking(true); }
  16.  public static void main(String[] args) {
  17.   Goods2 g= new Goods2();
  18.   g.track();
  19.  }
  20. }
    你不能在 if 之外创建这个内部类的对象,因为这已经超出了它的作用域。不过在编译的时候,内部类 TrackingSlip 和其他类一样同时被编译,只不过它由它自己的作用域,超出了这个范围就无效,除此之外它和其他内部类并没有区别。


    2.匿名类

    匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。
    这就要采用另一种形式的new语句,如下所示:

    new <类或接口> <类的主体>

    这种形式的new语句声明一个新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。
    假如匿名类对另一个类进行扩展,他的主体能够访问类的成员、覆盖他的方法等等,这和其他任何标准的类都是相同的。假如匿名类实现了一个接口,他的主体必须实现接口的方法。

    注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。

    从技术上说,匿名类可被视为非静态的内部类,所以他们具备和方法内部声明的非静态内部类相同的权限和限制。

    假如要执行的任务需要一个对象,但却不值得创建全新的对象(原因可能是所需的类过于简单,或是由于他只在一个方法内部使用),匿名类就显得很有用。匿名类尤其适合在Swing应用程式中快速创建事件处理程式。
    java 代码:

    Java代码 收藏代码
    1. interface pr {
    2.  void print1();
    3. }
    4. public class noNameClass {
    5.  public pr dest() {
    6.   return new pr() {
    7.    public void print1() {
    8.     System.out.println("Hello world!!");
    9.    }
    10.   };
    11.  }
    12. }
    13. public static void main(String args[]) {
    14.  noNameClass c = new noNameClass();
    15.  pr hw = c.dest();
    16.  hw.print1();
    17. }
      pr 也可以是一个类,但是你外部调用的方法必须在你的这个类或接口中声明,外部不能调用匿名类内部的方法。

      Java 中内部匿名类用的最多的地方也许就是在 Frame 中加入 Listner 了吧。
      java 代码:

      Java代码 收藏代码
      1. import java.awt.*;
      2. import java.awt.event.*;
      3. public class QFrame extends Frame {
      4.  public QFrame() {
      5.   this.setTitle(\"my application\");
      6.   addWindowListener(new WindowAdapter() {
      7.    public void windowClosing(WindowEvent e) {
      8.     dispose();
      9.     System.exit(0);
      10.    }
      11.   });
      12.   this.setBounds(10,10,200,200);
      13.  }
      14. }
        内部匿名类,就是建立一个内部的类,但没有给你命名,也就是没有引用实例的变量。
        Java代码 收藏代码
        1. new WindowAdapter() {
        2. public void windowClosing(WindowEvent e) {
        3. dispose();
        4. System.exit(0);
        5. }
        6. }

          new 是建立一个 WindowAdapter 对象,后面一个 {} 表示这个括号中的操作作用于这个默认的对名象,而上面的 Java 程序中后面是一个函数体。
          这个用法的作用是:创建一个对象的实例,并且 override 它的一个函数。
          打开 WindowAdapter 的代码可以发现。它是一个抽象类。它是对 WindowListener 接口的一个实现。
          Frame.addWindowListner(); 的参数是一个 WindowListner ,而实现上是传一个从WindowAdapter 派生出的一个匿名类。

          有一点需要注意的是,匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用 super 关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法:
          1. 如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为 final 。
          2. 将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了。
          3. 在这个匿名内部类中使用初始化代码块。