Java中的匿名内部类

一、什么是匿名内部类?

定义:巴拉巴拉巴拉,就不写了。

语法:

部分内容来源于:什么是匿名内部类,如何使用匿名内部类_Weihaom_的博客-CSDN博客_匿名内部类

二、为什么要有匿名内部类?

在开发过程中,我们经常会遇到某个类/接口中的方法在程序中只实现一次。如果用传统方式,为了使用该方法,我们需要新建一个实现类去extends/implements某个类/接口,然后实例化对象,再用对象去调用方法,很麻烦。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余

传统方式:很麻烦的,尤其是当method()方法,只使用一次的时候,为了这一次使用,去创建一个实现类,写这么多,太麻烦了!

package com.hspedu.innerClass;

public class AnonymousInnerClassMG {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
}

interface A {
    public void method();
}

class B implements A{
    @Override
    public void method() {
        System.out.println("我是方法");
    }
}

匿名内部类方式:作用是简化上面的代码

package com.hspedu.innerClass;

public class AnonymousInnerClassMG {
    public static void main(String[] args) {
        A a = new A() {
            @Override
            public void method() {
                System.out.println("我是method");
            }
        };
        a.method();
    }
}

interface A {
    public void method();
}

另外,匿名内部类那块还可以这样写:

package com.hspedu.innerClass;

public class AnonymousInnerClassMG {
    public static void main(String[] args) {
        new A() {
            @Override
            public void method() {
                System.out.println("我是method");
            }
        }.method();
    }
}

interface A {
    public void method();
}

Tips:

1、我们也用匿名内部类的方式去创建并启动线程:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("我是一个线程");
    }
}).start();

2、安卓开发中button的监听事件,也是用了匿名内部类。

三、匿名内部类是怎么实现的

看下面代码的注释应该就明白了:

package com.hspedu.innerClass;
/*
演示匿名内部类的使用
 */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04{  //外部类
    private int n1 = 10;  //属性
    public void method(){  //方法
        //基于接口的匿名内部类
        //1.需求:想使用IA接口,并创建对象
        //2.传统方式:是写一个类,实现该接口,并创建对象
        //3.现在的需求是Tiger/Dog类是只使用一次,后面再也不使用了,按照传统的写法就比较麻烦和浪费
        //4.于是使用匿名内部类来简化开发
        //5.tiger的编译类型?是IA
        //6.tiger的运行类型?就是匿名内部类,名称就是外部类$1。即Outer04$1
        /*
            我们看底层:Outer04$1就是我们的匿名内部类名字,这个名字是底层分配的,其实底层是有这个implement的行为
            class Outer04$1 implements IA{
                @Override
                public void cry() {
                    System.out.println("老虎叫");
                }
            }
         */
        //7.jdk底层在创建匿名内部类Outer04$1,立即马上就创建了Outer04$1实例,
        //并把地址返回给了tiger
        //8.匿名内部类使用一次,就不能再使用了(不是tiger对象哦)
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫");
            }
        };
        System.out.println("tiger的运行类型= " + tiger.getClass());  //tiger.getClass()就是获得tiger对象的运行类型
        tiger.cry();
    }
}

interface IA{  //接口
    public void cry();
}

四、匿名内部类可以用在哪里

对接口、具体类、抽象类都可以使用匿名内部类,而且对方法的个数没有要求。

//具体类
public class Class01 {
    public void show(String s){
        System.out.println("啦啦啦");
    }
}

//抽象类
public abstract class AbstractClass01 {
    abstract void show(String s);
}

//接口
public interface Interface01 {
    void show(String s);
}

public class TestInner {
    public static void main(String[] args) {
        
        //重写具体类的方法
        new Class01(){
            @Override
            public void show(String s) {
                System.out.println("我是一个" + s);
            }
        }.show("具体类");

        //重写抽象类的抽象方法
        new AbstractClass01(){
            @Override
            void show(String s) {
                System.out.println("我是一个" + s);
            }
        }.show("抽象类");

        //实现接口的抽象方法
        new Interface01(){
            @Override
            public void show(String s) {
                System.out.println("我是一个" + s);
            }
        }.show("接口");

    }
}

运行结果

我是一个具体类
我是一个抽象类
我是一个接口

五、匿名内部类的细节

1、匿名内部类的语法比较奇特,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,从语法上看,既有定义类的特征,也有创建对象的特征。

左图是因为匿名内部类new A(){}也是一个对象,因此是直接调用了cry方法。

右图是因为匿名内部类也是一个类,所以用实例化的对象a去调用cry方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m1m-FG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值