匿名内部类笔记

一 . 匿名内部类的基本语法:

new 类 / 接口(参数){

        类体

} ;

匿名内部类本质是一个类 , 通常写在方法中 , 没有名字(名字是由系统给出的) , 同时也是一个对象 ;

二 .  基于接口的匿名内部类 :

1. 对于接口来说什么时候最好使用匿名内部类 :

interface A //接口
{
    public void cry();
}
class Tiger implements A
{
    @Override
    public void cry()
    {
        System.out.println("老虎..");
    }
}

class TestMain
{
    public static void main(String[] args) {
        //向上转型
        A tiger=new Tiger();
        //只使用一次,还得再新创建一个Tiger类去实现接口A, 很麻烦
        tiger.cry();
    }
}

2. 为了避免这种只使用一次这个Tiger类 , 并且还要再创建这个类来实现接口的这种情况, 我们可以采用匿名内部类 来简化开发 , 就不需要再新创建一个Tiger类了 : 

public class Outer { //外部类
    private int n1=100;
    //在方法内写匿名内部类
    public void method()
    {
        //tiger 的编译类型:接口A;
        //tiger 的运行类型:不是接口A,因为接口是抽象类创建不了对象的,tiger的运行类型就是匿名内部类;
        A tiger=new A() {
            @Override
            public void cry() {
                System.out.println("老虎..");
            }
        };
        tiger.cry();
    }
}

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

class TestMain
{
    public static void main(String[] args) {
        //使用外部类来创建对象
        Outer tiger=new Outer();
        //调用方法
        tiger.method();
    }
}

3. 在底层创建了匿名内部类 Outer$1 , 立即就new创建了实例对象 (这也就是为什么说匿名内部类还是一个对象)  , 并把地址返回给tiger ,所以tiger此时引用的是Outer$1的对象:

解释匿名内部类为什么也是对象 : 因为匿名内部类实现接口 / 继承父类后 ,由于匿名内部类的格式是new 接口/父类 ,所以会直接创建对象 , 所以在使用匿名内部类的时候它本质就是一个对象 .

public class Outer { //外部类
    private int n1=100;
    //在方法内写匿名内部类
    public void method()
    {
        /*
        底层是通过系统用一个匿名的类来实现这个接口的实现:
        这个类名 XXXX 由系统给出,可以通过getClass方法来获取tiger的运行类型: 就是外部类名$1(Outer$1)
        class XXXX implements A {
            @Override
            public void cry()
            {
                System.out.println("老虎..");
            }
        }
        */
        //直接用匿名内部类创建一个对象,让tiger引用这个对象,就可以实现接口并调用重写后的方法了:
        A tiger = new A() {
            @Override
            public void cry() {
                System.out.println("老虎..");
            }
        };
        System.out.println("tiger的运行类型: "+tiger.getClass());
        tiger.cry();
    }
}

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

class TestMain
{
    public static void main(String[] args) {
        //使用外部类来创建对象
        Outer tiger=new Outer();
        //调用方法
        tiger.method();
    }
}

三 .基于类的匿名内部类 :

和基于接口是相似的 , 只不过匿名内部类是实现接口 , 对于类来说匿名内部类是继承此类 .

public class Outer { //外部类
    private int n1=100;
    //在方法内写匿名内部类
    public void method()
    {
        /*
        底层是通过系统用一个匿名内部类来继承这个Father类:
        这个类名 XXXX 由系统给出,可以通过getClass方法来获取father的运行类型: 就是外部类名$1(Outer$1)
        class XXXX extends Father{
            @Override
            public void test()
            {

            }
        }
        如果这样写则不会产生匿名内部类,因为这只是用Father来创建了一个对象,所以要想使用匿名内部类必须要有{};
        Father father=new Father("jack");
        */


        //基于类的匿名内部类:
        //father的编译类型: Father
        //father的运行类型: Outer$1
        //Father("jack")会调用Father中的构造方法;
        Father father=new Father("jack"){
            //匿名内部类继承了Father类 ,这里面可以重写Father类中的方法也可以不重写,因为这不是接口;
        };
        System.out.println("father的运行类型: "+father.getClass());
    }
}

class Father
{
    //构造方法:
    public Father(String name)
    {
        System.out.println("接收的name是:"+name);
    }
    //普通方法:
    public void test()
    {

    }
}

class TestMain
{
    public static void main(String[] args) {
        //使用外部类来创建对象
        Outer father=new Outer();
        //调用方法method
        father.method();
    }
}

四 . 把匿名内部类作为实参传递 , 简洁高效 :

public class test {
    public static void main(String[] args) {
        //如果只使用一次最好使用匿名内部类作为实参传递
        //由匿名内部类来实现接口A1,因为匿名内部类也是一个对象,所以匿名内部类作为实参直接传递,简洁高效
        f1(new A1() {
            @Override
            public void show()
            {
                System.out.println("这是匿名内部类作为实参");
            }
        });

        //如果传入多次new B(),最好使用传统方法;
        //传统方法:写一个B类来实现接口A1,再创建B类的对象作为实参传入f1中:
        f1(new B());
    }

    //静态方法,形参是接口类型
    public static void f1(A1 a1)
    {
        a1.show();
    }
}

interface A1
{
    void show();
}

class B implements A1
{
    @Override
    public void show()
    {
        System.out.println("这是B类对象作为实参");
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值