用大白话聊聊匿名内部类

再细说匿名内部类之前,我们想一个问题,我们再用接口的时候是不是需要先让一个类去实现这个接口,而我们在用一个抽象类时,是不是也得让一个类去继承这个抽象类才能用其中抽象方法;我们把这个类叫做老好人吧,每次取用接口中和抽象类当中的抽象方法时都得去委托这个老好人,现在我们想解放这个老好人,于是出现了匿名内部类

 一、匿名内部类的定义

  1. 最本质的还是一个类
  2. 是一个内部类(有关内部类的内容不在这里讲述了)
  3. 该类没有名字(但是系统会分配一个代号在内存中

二、匿名内部类的应用场景

假设我们有一个接口A
内部有一个未被实现的方法eat
如果我们想在main中直接调用eat方法
则按照传统思路需要一个类B来实现接口A,同时再创建类B的对象来调用A
代码如下:

public class Interface01 {
    public static void main(String[] args) {
        B b = new B();
        b.eat();
    }
}
interface A{
    public void eat();
}
class B implements A{
    @Override
    public void eat() {
        System.out.println("正在调用eat方法");
    }
}
----------------------
正在调用eat方法

如果我们只是想单纯的使用一次eat方法,不需要创建对象的话,则上面方法略显古板。
此时,便用到了匿名内部类。

public class Interface01 {
    public static void main(String[] args) {
        new A(){
            @Override
            public void eat() {
                System.out.println("正在调用eat方法");
            }
        }.eat();
    }
}
interface A{
    public void eat();
}
----------------------
正在调用eat方法

上面这种写法就可以很好的简化代码的书写
此时的匿名内部类相当于一个对象,所以它的后面可以直接调用eat方法,非常的简便快捷
当A里面有多个方法时,如果想要同时调用,可以采用下面的写法:

public class Interface01 {
    public static void main(String[] args) {
        A a = new A(){
            @Override
            public void eat() {
                System.out.println("正在调用eat方法");
            }
            public void drink(){
                System.out.println("正在调用drink方法");
            }
        };
        a.eat();
        a.drink();
    }
}
interface A{
    public void eat();
    public void drink();
}

而此时我们并没有实例化这个接口的类,便实现了里面的方法,所以称之为匿名内部类
其实,这个类是被临时创建了,在内存中存在系统设定的名字,
我们可以使用下面方法来得到匿名内部类的(名字)

public class Interface01 {
    public static void main(String[] args) {
        A a = new A(){
            @Override
            public void eat() {
                System.out.println("正在调用eat方法");
            }
            public void drink(){
                System.out.println("正在调用drink方法");
            }
        };
        a.eat();
        a.drink();
        System.out.println(a.getClass()); //获取类名
    }
}
interface A{
    public void eat();
    public void drink();
}
-------------------
正在调用eat方法
正在调用drink方法
class com.interface_.Interface01$1

由此可见,这个匿名内部类的名字为Interface01$1,当下一个匿名内部类时,就会变成$2,以此类推

三、匿名内部类的最常使用场景

通过实参的形式来使用,大大简化了代码的书写

public class Interface01 {
    public static void main(String[] args) {
        f(new A() {
            @Override
            public void eat() {
                System.out.println("没有创建对象便成功的调用了f方法,不需要实现接口");
            }
        });
    }
    public static void f(A a){
        a.eat();
    }
}
interface A{
    public void eat();
}
---------------------------
没有创建对象便成功的调用了f方法,不需要实现接口

而按照传统方法则需要:

public class Interface01 {
    public static void main(String[] args) {
        B b = new B();
        f(b);
    }
    public static void f(A a){
        a.eat();
    }
}
interface A{
    public void eat();
}
class B implements A{
    @Override
    public void eat() {
        System.out.println("正在调用eat方法");
    }
}
--------------
正在调用eat方法

四、Java匿名内部类的注意事项

在使用匿名内部类的过程中,我们需要注意如下几点:

    1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

    2、匿名内部类中是不能定义构造函数的。

    3、匿名内部类中不能存在任何的静态成员变量和静态方法。

    4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。

    5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
 

参考Boyka_Xue

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值