java 匿名类

        匿名类(Anonymous Class) 是一种没有名字的类,通常在需要创建某个接口或类的实例时,临时实现其功能,而无需专门为其编写独立的类定义。匿名类在 Java 中广泛用于事件处理、线程、回调等场景,尤其是那些只需要一次性使用的类或接口实现。

1. 匿名类的语法

interface Greeting {
    void sayHello();
}

public class AnonymousClassExample {
    public static void main(String[] args) {
        // 使用匿名类来实现 Greeting 接口
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello() {
                System.out.println("Hello from Anonymous Class!");
            }
        };
        
        greeting.sayHello();  // 输出:Hello from Anonymous Class!
    }
}

匿名类实现一个接口。

2.匿名类特点

匿名类就像是一个临时创建的类实例,直接在代码中定义,而不需要专门去编写一个完整的类。它类似于在特定场景下临时创建一个“参数”,这个“参数”是指实现某个接口或继承某个类的匿名实现。具体来说:

  • 没有名字:匿名类没有类名,通常直接定义并实例化。
  • 简化代码:不需要专门创建类文件来实现接口或继承类,可以在代码中临时实现一个接口或类。
  • 局部使用:匿名类常用于局部场景,如方法内部,只使用一次。
  • 只能创建一个实例:因为匿名类不能被多次复用,所以每次使用时都会重新定义和实例化。
  • 临时创建:匿名类通常是为了满足某个即时需求,只在局部使用一次,所以没有类名,不能复用。
  • 直接实现接口/类:你可以通过匿名类创建一个实现某个接口或者继承某个类的对象,而不需要定义一个额外的类文件。
  • 临时的行为:匿名类的作用相当于创建了一个临时的对象,这个对象会实现某些特定的行为,但在完成它的任务后,就不再被使用。

虽然匿名类没有名字,但它依然是一个合法的类,因此可以调用该匿名类中实现的方法。匿名类的核心是实现接口或继承一个类,它可以像任何普通类一样定义和实现方法,只不过这个类没有名字。

匿名类也可以定义额外的方法,但这些方法只能在匿名类内部调用,因为匿名类没有名字,外部没有直接的途径来访问这些方法。

public class AnonymousClassExample {
    public static void main(String[] args) {
        // 使用匿名类
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello() {
                System.out.println("Hello from Anonymous Class");
                // 调用匿名类的私有方法
                sayPrivateHello();
            }

            // 匿名类的自定义方法
            private void sayPrivateHello() {
                System.out.println("Hello from Private Method");
            }
        };

        // 调用匿名类中实现的接口方法
        greeting.sayHello();  // 输出: Hello from Anonymous Class
                              //      Hello from Private Method
    }
}

使用父类的匿名类

// 定义父类 Animal
class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

public class AnonymousClassExample {
    public static void main(String[] args) {
        // 创建一个匿名类,继承 Animal 类,并重写 sound 方法
        Animal dog = new Animal() {
            @Override
            public void sound() {
                System.out.println("Dog barks");
            }
        };

        // 创建另一个匿名类,继承 Animal 类,并重写 sound 方法
        Animal cat = new Animal() {
            @Override
            public void sound() {
                System.out.println("Cat meows");
            }
        };

        // 调用父类中的方法
        dog.sound();  // 输出: Dog barks
        cat.sound();  // 输出: Cat meows
    }
}

可以看到,创建匿名类的代码是

        Animal dog = new Animal() {
            @Override
            public void sound() {
                System.out.println("Dog barks");
            }
        };

我们知道,Animal是一个对象,而new Animal()这是在进行对象的实例化。但这里却不同,平时,对象的实例化是new Animal();  而这里是new Animal(){},这就是在创建匿名类,同时进行了匿名类的实例化,这个匿名类是Animal的子类,是对Animal的继承,其可以重写父类的方法,拥有父类的所有特性,甚至添加新的方法。dog的类型是Animal 但其指向的是匿名子类的实例化,这是多态

3.匿名类的应用场景

a. 事件处理

在 GUI 编程中,匿名类常用于为按钮点击等事件添加事件处理器。例如,使用 Swing 创建按钮的点击事件处理程序:

import javax.swing.JButton;
import javax.swing.JFrame;

public class ButtonExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Anonymous Class Example");
        JButton button = new JButton("Click me");

        // 使用匿名类来处理按钮点击事件
        button.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent e) {
                System.out.println("Button clicked!");
            }
        });

        frame.add(button);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}
b. 线程

使用匿名类实现 Runnable 接口,简化线程创建:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Thread is running");
    }
}).start();
c. 回调

在异步任务中使用匿名类实现回调函数。例如,网络请求的回调处理可以通过匿名类实现:

fetchData(new Callback() {
    @Override
    public void onSuccess(String result) {
        System.out.println("Data received: " + result);
    }

    @Override
    public void onFailure(Exception e) {
        System.out.println("Request failed");
    }
});

4.匿名类与 Lambda 表达式的关系

Java 8 引入 Lambda 表达式 之后,很多使用匿名类的场景可以被 Lambda 表达式替代,特别是在实现 函数式接口 的时候。

使用匿名类实现 Runnable 接口:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Thread is running");
    }
}).start();

使用 Lambda 表达式实现 Runnable 接口:

new Thread(() -> System.out.println("Thread is running")).start();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值