下面有一个更怪的例子:
Java代码
- public class Goods2{
- private void internalTracking(boolean b) {
- if(b) {
- class TrackingSlip {
- private String id;
- TrackingSlip(String s) {
- id = s;
- }
- String getSlip() { return id; }
- }
- TrackingSlip ts = new TrackingSlip("slip");
- String s = ts.getSlip();
- }
- }
- public void track() { internalTracking(true); }
- public static void main(String[] args) {
- Goods2 g= new Goods2();
- g.track();
- }
- }
你不能在 if 之外创建这个内部类的对象,因为这已经超出了它的作用域。不过在编译的时候,内部类 TrackingSlip 和其他类一样同时被编译,只不过它由它自己的作用域,超出了这个范围就无效,除此之外它和其他内部类并没有区别。
2.匿名类
匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。
这就要采用另一种形式的new语句,如下所示:
new <类或接口> <类的主体>
这种形式的new语句声明一个新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。
假如匿名类对另一个类进行扩展,他的主体能够访问类的成员、覆盖他的方法等等,这和其他任何标准的类都是相同的。假如匿名类实现了一个接口,他的主体必须实现接口的方法。
注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。
从技术上说,匿名类可被视为非静态的内部类,所以他们具备和方法内部声明的非静态内部类相同的权限和限制。
假如要执行的任务需要一个对象,但却不值得创建全新的对象(原因可能是所需的类过于简单,或是由于他只在一个方法内部使用),匿名类就显得很有用。匿名类尤其适合在Swing应用程式中快速创建事件处理程式。
java 代码:
Java代码
- interface pr {
- void print1();
- }
- public class noNameClass {
- public pr dest() {
- return new pr() {
- public void print1() {
- System.out.println("Hello world!!");
- }
- };
- }
- }
- public static void main(String args[]) {
- noNameClass c = new noNameClass();
- pr hw = c.dest();
- hw.print1();
- }
pr 也可以是一个类,但是你外部调用的方法必须在你的这个类或接口中声明,外部不能调用匿名类内部的方法。
Java 中内部匿名类用的最多的地方也许就是在 Frame 中加入 Listner 了吧。
java 代码:
Java代码
- import java.awt.*;
- import java.awt.event.*;
- public class QFrame extends Frame {
- public QFrame() {
- this.setTitle(\"my application\");
- addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- dispose();
- System.exit(0);
- }
- });
- this.setBounds(10,10,200,200);
- }
- }
内部匿名类,就是建立一个内部的类,但没有给你命名,也就是没有引用实例的变量。
Java代码
- new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- dispose();
- System.exit(0);
- }
- }
new 是建立一个 WindowAdapter 对象,后面一个 {} 表示这个括号中的操作作用于这个默认的对名象,而上面的 Java 程序中后面是一个函数体。
这个用法的作用是:创建一个对象的实例,并且 override 它的一个函数。
打开 WindowAdapter 的代码可以发现。它是一个抽象类。它是对 WindowListener 接口的一个实现。
Frame.addWindowListner(); 的参数是一个 WindowListner ,而实现上是传一个从WindowAdapter 派生出的一个匿名类。
有一点需要注意的是,匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用 super 关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法:
1. 如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为 final 。
2. 将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了。
3. 在这个匿名内部类中使用初始化代码块。