第三天 匿名内部类

匿名对象

概念

  • 匿名对象:没有名字的类就

使用场景

  • 作为参数传递
    ArrayList<Student> list = new ArrayList<Student>();
    list.add(new Student("tom",13));
    
  • 对象的方法只调用一次
    new Student("tom",13).eat();	
    

内部类

概念

  • 内部类:类里边的类

成员内部类

  • 定义在成员位置的类
  • 成员内部类可以直接使用外部类中的数据
  • 格式:
    public class Outer{
    	class Inner{
    		public void show(){
    			System.out.println("使用内部类的方法");
    	}
    }	
    
    调用成员内部类的方法:
    Outer.Inner inner = new Outer.new Inner();
    inner.show
    

局部内部类

  • 定义在局部位置的类
  • 格式
    public class Outer{
    	
     public void show() {
            final int num = 666;
            class Inner {
                public void func() {
                    System.out.println(num);
                }
            }
            new Inner().func();
        }
    }
    
  • 为什么内部类使用局部变量的时候要用final修饰?
    – 因为new Inner()当方法show()执行完毕后有可能还在内存中,但是这个对象中的是func()方法使用局部变量num,如果局部变量num没有被final修饰,那么方法执行完就没了,这样就引用了一个不存在的变量,程序就会报错。所以我们要使用fianl延长num变量的生命周期。

使用内部类的场景

  • 如果A类只在B类中使用到,那么我们就可以把A类定义成B类的内部类。

匿名内部类

  • 接口
    public interface Ai {
       void speak();
    }
    
  • 匿名内部类的使用
    pulic class Test{
    	public static void main(String[] args){
    	/*格式:new 类名/接口名(){重写父类或者父接口中的方法{}表示类,
    	因为没有类名,并且这个类定义在类里边,所以称之为匿名内部类这个
    	类的本质是实现了Interesting接口的子类,所以要重写接口中的方法
    	*/   
    	new Ai() {
            public void speak(){
                System.out.println("China is No.1");
            }
        }.speak();
    
  • 使用场景one
    – 接口的方法中调用了一次,那么我们就没有必要在重新创建一个类,这个时候直接使用匿名内部类就可以了(参照匿名内部类的使用)
  • 使用场景two
    – 如果在调用方法的时候用接口接受数据,我们可以直接传入一个匿名内部类对象,这样就省去了新建类的麻烦。
    //格式
    public static void show(接口类 inter){
    	inter.speak();
    }
    //定义接口
    public interface Ai {
        void speak();
    }
    //主方法	
    public static void main(String[] args) {
       show(new Ai(){ //调用show方法
           public void speak(){  //匿名内部类
               System.out.println("chinese is No.1");
           }
       });
    }
    
    public static void show(Ai ai){ 定义show方法  ai只能使用接口里的方法
        ai.speak();
    }
    

个人总结

  • 匿名内部类:实现接口,抽象类和普通类的匿名内部类都可以,但是接口和抽象类的方法都必须重写。
  • 实用的只有匿名内部类(或者是有抽象方法的抽象类),主要是为了调用(重写了的抽象方法)父类的方法
  • 内部类能被private修饰?不能
  • 成员内部类能用private修饰的成员变量吗?可以
    局部内部类的疑问:
    1.定义在方法内的类,方法内创建对象然后调用内部类的方法,实例化对象必须在方法内,内部类外(假如定义在内部类里,那么实例化的时候,进入一个死循环类)
    2.匿名内部类的定义 本质是实现了父类接口的子类对象
    3.内部类里可以用private修饰成员内容(反正只能通过内部类直接调用,所以权限修饰符对内部类的成员变量没有要求)

匿名内部类的问题

1、为什么不能具有静态成员域和成员函数、静态代码块、static final修饰的引用类型、静态内部类?

答:和实名内部类类似,“静态”意味着与实例对象无关就可以访问,从匿名内部类的使用我们可以看到,其一定会实例化一个对象,此时使用“静态”便毫无意义。static final修饰引用类型的目的:1、不需要实例对象就可访问,2、不希望指针指向改变,匿名内部类的使用方式使1变得毫无意义,所以规定不能用static final修饰引用类型,由于匿名内部类没有名字,想要使用静态内部类必须通过一个匿名内部类的实例对象,与“静态”定义矛盾。

2、为什么不能有自定义构造函数?

答:从class文件中,我们可以看到匿名内部类其实含有编译器自动加上的构造函数,且JVM只调用该构造函数,自定义构造函数无效,另外,匿名内部类名字都没有怎么定义构造函数(滑稽.jpg)?

3、为什么匿名内部类不能有类修饰符?

emmmm,加类修饰符可能与有效域冲突,例如加public,但匿名内部类只在当前作用域或是当前行有效,且这些类修饰符本来就是规定访问范围的,但匿名内部类访问范围已经规定。

4、为什么可以有static final修饰的具有字面量的变量?

其实对于匿名内部类来说,static final与final修饰的具有字面量的变量效果一样,只是初始化时机不一样,保存位置不一样,对于性能没有太多影响,所以保留。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值