java匿名内部类

来源:互联网 发布:淘宝密令符号 编辑:程序博客网 时间:2024/05/21 10:04

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 匿名内部类 的基础知识;
0.2) 我们还由匿名内部类引出了 匿名子类


【1】匿名内部类(在方法中创建一个类的一个对象)

1.1)匿名内部类定义:将局部内部类的使用再深入一步,假如只创建这个类的一个对象,就不必命名了(对下图进行比较);

1.2)这种语法确实有些难以理解, 它的含义是:创建一个实现 ActionListener 接口的类的新对象, 需要实现的方法 actionPerformed 定义在括号{} 内;
1.3)通常的语法格式为:

new SuperType(construction parameters){    inner class methods and data}
  • 1.3.1)其中, SuperType 可以是 ActionListener这样的接口, 于是内部类就要实现这个接口。SuperType 也可以是一个类, 于是内部类就要扩展它;
  • 1.3.2)由于构造器的名字必须与类名相同, 而匿名类没有类名, 所以,匿名类不能有构造器; 取而代之的是, 将构造器参数传递给 超类构造器;
  • 1.3.3)不仅如此,还要像下面这样提供一组括号:
new interfaceType(){    methods and data}

1.3.4)如果构造参数的闭圆括号跟一个花括号,正在定义的就是 匿名内部类;
这里写图片描述

package com.corejava.chapter6_3;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Date;import javax.swing.JOptionPane;import javax.swing.Timer;public class AnonymousInnerClassTest{    public static void main(String[] args)    {        TalkingClock111 clock = new TalkingClock111();        clock.start(1000, true);        // keep program running until user selects "Ok"        JOptionPane.showMessageDialog(null, "Quit program?");        System.exit(0);    }}class TalkingClock111{    public void start(int interval, final boolean beep)    {        ActionListener listener = new ActionListener()        {            public void actionPerformed(ActionEvent event)            {                Date now = new Date();                System.out.println("At the tone, the time is " + now);                if (beep)                    Toolkit.getDefaultToolkit().beep();            }        };        Timer t = new Timer(interval, listener);        t.start();    }}

Annotation)

  • A1)下面的技巧称为“双括号初始化”, 这里利用了内部类语法,假设你想构造一个数组列表, 并将它传递到一个方法:
ArrayList<String> friends = new ArrayList<>();friends.add("A");friends.add("B");invite(friends);
  • A2)匿名列表: 如果不再需要这个数组列表, 最好让它作为一个匿名列表;
    这里写图片描述
  • A3)注意这里的双括号: 外层括号建立了 ArrayList 的一个匿名子类。内层括号是一个 对象构造块;

Warning) 建立一个与超类大体类似(但不完全相同)的匿名子类通常会很方便。不过, 对于 equals 方法要特别当心。第5章中, 我们曾经建议 equals 方法最好使用以下测试:

if(getClass() != other.getClass() ) return false;

但是对匿名子类做这个测试时会失败;

Hint)

  • H1)生成日志或调试消息时, 通常希望包含当前类的类名, 如:
    System.err.println(“something awful happened in” + getClass() );
    不过, 这对于静态方法不奏效。毕竟调用getClass 时调用的是 this.getClass(), 而静态方法没有this, 应该使用以下表达式:
    new Object(){}.getClass().getEnclosiingClass() // gets class of static method
  • H2)在这里, new Object() 会建立Object的一个匿名子类的一个匿名对象, getEnclosingClass 则得到其他外围类, 也就是包含这个静态方法的类;
0 0