JAVA匿名内部类

匿名内部类的特征

1、匿名内部类的本质还是一个类

2、匿名内部类是一个内部类,嵌入在另一个类中

3、匿名内部类没有名字

4、匿名内部类同时也是一个对象

匿名内部类的引入

如果我们有一个IA接口,想使用接口中的方法,那么我们应该怎样做?

传统方法:

先实现IA接口 --->实现IA接口---> 创建实现IA接口对应类的对象---->调用方法

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.hi();
    }
}
interface IA{
    public void eat();
}

class Cat implements IA {
    @Override
    public void eat() {
        System.out.println("小猫吃鱼~");
    }    
}
class Outer{
    public void hi() {
        Cat cat = new Cat();
        cat.eat();
    }    
}
----------------------
小猫吃鱼~

传统方法可以实现需求,但是会显得冗余麻烦。如果进一步提出需求:接口中的方法只使用一次,以后再也不使用了,那么就可以使用匿名内部类精炼的来解决这个问题,不用创建类来实现接口也可以

匿名内部类方法

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.hi();

    }
}

interface IA {
    public abstract void eat();
}

class Outer {
    public void hi() {//方法

        IA cat = new IA() {
            @Override
            public void eat() {
                System.out.println("小猫吃鱼~");
            }
        };
        cat.eat();
    }
}
-------------------
小猫吃鱼~

而此时我们并没有实例化这个接口的类,便实现了里面的方法,所以称之为匿名内部类

其实这个类是被临时创建的,在JDK中有类的名字

以上面为例,在JDK底层上会创建一个实现了IA接口的类Outer$1,该类被创建的瞬间就会实例一个Outer$1对象,然后把对象地址传递给 cat

匿名内部类只能使用一次,使用完就不能再用了。

JDK底层匿名内部类创建过程

JDK底层创建Outer$1类的过程大概如下(以上面代码为例)

class Outer$1 implements IA {
                @Override
                public void eat() {
                    System.out.println("小猫吃鱼~");
                }
            }

然后  new Outer$1() , 把对象返回给cat

我们可以验证一下 cat 的运行类型是不是Outer$1

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.hi();

    }
}

interface IA {
    public abstract void eat();
}

class Outer {
    public void hi() {//方法

        IA cat = new IA() {
            @Override
            public void eat() {
                System.out.println("小猫吃鱼~");
            }
        };
        cat.eat();
        System.out.println("cat对象的运行类型=" + cat.getClass);
    }
}
-------------------
小猫吃鱼~
cat对象的运行类型=class com.zkyedu.innerclass.Outer$1

可以看到结尾运行类型正是Outerus$1

如果创建想创建不同的对象,那么匿名内部类的类名后面的数字会逐渐增加Outerus$1 ,Outerus$2 ..........

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.hi();

    }
}

interface IA {
    public abstract void eat();
}

class Outer {
    public void hi() {//方法

        IA cat = new IA() {
            @Override
            public void eat() {
                System.out.println("小猫吃鱼~");
            }
        };
         IA dog = new IA() {
            @Override
            public void eat() {
                System.out.println("小狗吃骨头~");
            }
        };
        cat.eat();
        System.out.println("cat对象的运行类型=" + cat.getClass);
        System.out.println("dog对象的运行类型=" + dog.getClass);
    }
}
-------------------
小猫吃鱼~
cat对象的运行类型=class com.zkyedu.innerclass.Outer$1
dog对象的运行类型=class com.zkyedu.innerclass.Outer$2

!!!注意匿名内部类的作用域是在定义它的方法或者代码块中,外部其他类不能访问匿名内部类,如果想访问可以创建外部类对象,然后调用方法。

匿名内部类的使用细节

1、可以直接访问外部类的所有成员,包含私有的

2、不能添加访问修饰符,因为它的地位就是一个局部变量

3、.如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)  

4、作用域 : 仅仅在定义它的方法或代码块中

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值