内部类总结

内部类是java中比较复杂的内容,接下来进行一些细节总结:

 

内部类(inner class)是定义在一个类中的类,这种技巧有什么好处呢?

  • 内部类可以访问外部类中的数据,包括私有数据
  • 内部类对于包中其它类来说是隐藏的
  • 当想要定义一个回调(callback)函数时,可以使用匿名内部类,这样更为便捷

  (回调函数:可以指出一个特定事件发生时应该采取的动作.例如在按下鼠标或选择某个菜单时应该采取什么行动)

 

1.使用内部类访问对象状态:

public class TalkingClock
{
    private int interval;
    private boolean beep;

    public TalkingClock(int interval, boolean beep) { . . . }
    public void start() { . . . }

    public class TimePrinter implements ActionListener //内部类

    {
        . . .
    }
}            

内部类的详细代码:

public class TimePrinter implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        System.out.println("At the tone, the time is " + new Date());
        if (beep) Toolkit.getDefaultToolkit().beep();
    }
}    

可以发现,在内部类中的beep是外部类中的变量,这样的引用是如何做到的呢?

事实上,是通过这样一种方式调用的    if (outer.beep) Toolkit.getDefaultToolkit().beep();

但是,outer并不是java中的关键字,可以看到,内部类并没有构造器,所以编译器隐式地给内部类了一个构造器:

public TimePrinter(TalkingClock clock)
{
    outer = clock;
}

 

2.内部类的特殊语法规则:

事实上,内部类对外部类引用的语法还要复杂一点:outerclass.this表示外部类数据的引用,如:

public class TimePrinter implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        System.out.println("At the tone, the time is " + new Date());
        if (outer.this.beep) Toolkit.getDefaultToolkit().beep();
    }
}   

细节规则:

  • 内部类中所有的静态域都必须是final,因为对于一个外部类的实例,我们希望它都只有唯一一个内部类实例
  • 内部类不能有静态方法

 

3.局部内部类:

如果内部类只在外部类的一个方法中调用了一次,我们可以采取使用局部内部类来简化代码:

public void start()
{
    class TimePrinter implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            System.out.println("At the tone, the time is " + new Date());
            if (beep) Toolkit.getDefaultToolkit().beep();
        }
    }
    ActionListener listener = new TimePrinter();
    Timer t = new Timer(interval, listener);
    t.start();
}

局部内部类不能用public和private来声明,它的作用域只限于在这个局部的块中

局部内部类的另一个优点是对外部世界完全隐蔽,即除了start()方法外,没有任何方法知道TimePrinter类

 

细节规则:

  • 当局部内部类访问局部变量时,必须为final
    int counter = 0;
    Date[] dates = new Date[100];
    for (int i = 0; i < dates.length; i++)
        dates[i] = new Date()
            {
                public int compareTo(Date other)
                {
                    counter++; //错误
                    return super.compareTo(other);
                }
            };
    Arrays.sort(dates);
    System.out.println(counter + " comparisons.");

     

4.匿名内部类:

语法格式:

new SuperType(construction parameters)
{
    inner class methods and data
}

例:

public void start(int interval, boolean beep)
{
    ActionListener listener = new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            System.out.println("At the tone, the time is " + new Date());
            if (beep) Toolkit.getDefaultToolkit().beep();
        }
    };
    Timer t = new Timer(interval, listener);
    t.start();
}

细节规则:

  • 由于构造器的名字必须与类相同,但是匿名内部类没有名字,所以匿名内部类没有构造器

 

posted @ 2017-04-06 14:50  NOthingAJ  阅读(163)  评论(0编辑  收藏  举报