java匿名内部类

【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)匿名列表: 如果不再需要这个数组列表, 最好让它作为一个匿名列表;
    java匿名内部类_第1张图片
  • 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 则得到其他外围类, 也就是包含这个静态方法的类;

你可能感兴趣的:(java,匿名内部类)