黑马程序员技术交流社区

标题: 匿名内部类,你学会了吗? [打印本页]

作者: 小蜀哥哥    时间: 2017-10-21 22:32
标题: 匿名内部类,你学会了吗?
本帖最后由 小蜀哥哥 于 2017-10-21 22:42 编辑

关于java中匿名内部类的学习


1. 为什么要学习匿名内部类:

    匿名内部类是java里头比较常用的一种结构,然而多数初学者可能对匿名内部类的使用会存在一部分问题,接下来我们就一起来探究关于匿名内部类的使用。在学习匿名内部类之前,我们应该学习完面向对象的三大特性并且清楚接口相关概念,因为在匿名内部类的学习中会需要使用到这些特性。

2. 那我们应该什么时候用匿名内部类呢?

    a) 如下图所示:在Test类中,method方法参数列表上定义的参数类型是一个接口Inner类型,由于接口不能创建对象,根据多态的特性,调用这个方法我们可以传递的是Inner的子类对象。


    b) 那么如果我们要调用这个方法,那么我们要做的工作就有两个,第一:定义该接口Inner的实现类,第二:创建该实现类的对象。

    c) 通过以上的步骤我们完成了对Test类中method方法的调用。但是重点就来了,如果学会了匿名内部类,通过使用匿名内部类,我们就可以一步做到以上定义Inner子类和创建其子类对象这两个工作。

3. 那么该怎么用呢?

    a) 首先要搞清楚两点:
        i. 创建匿名内部类的前提是有一个父类或者父接口,而我们待会创建出来的匿名内部类会是这个父类或者父接口的子类。
        ii. 匿名内部类指的是没有类名的内部类,那么一个类没有名字我们该如何创建对象呢?答案是:我们要将定义该接口的子类和创建其对象两个步骤揉在一起。
    b) 匿名内部类的定义格式:
          new 父类/父接口名(){
              //大括号相当于子类的定义
          }
        ii. 格式解读:
              1. new 父类/父接口():其实是创建了一个此父类或者父接口的子类对象
              2. {}:大括号中是对这个子类的定义,和我们通常定义类没有什么区别。如果父类或者父接口中有抽象方法,应该在区域此实现。(如下图所示,Inner这个接口中有一个抽象方法,于是我们就在这对大括号中实现了这个抽象方法)

       iii. 那么到了这一步,我们就已经创建出了匿名内部类,这相当于同时完成了定义类和创建对象的两个步骤。
    c)使用匿名内部类:
        i. 接下来我们如果要调用Test类中的method方法就可以按照上面的格式定义出一个匿名内部类了。
        ii. 注意:这个匿名内部类整体就是一个对象,所以我们直接就可以把它当作调用方法时传递的实际参数。

    d) 那么以上我们就已经完成了对匿名内部类的定义和使用。接下来我们还需要去了解一些使用中的注意事项。
4. 注意事项:

    a) 首先我们要明白的是,匿名内部类其实就相当于一个定义在方法中的类,有时候我们除了直接使用匿名内部类外,也可能会在匿名内部类的方法中使用外部类方法中的一些变量。
    b) 但是,当我们直接使用此匿名内部类所在方法的局部变量,显示编译错误:

        那么,究竟是什么原因导致了匿名内部类不能直接使用外部类方法中的局部变量呢?一起去探个究竟。
    c) 问题探究:
        i. 局部变量的作用域是在此方法中,当这个方法调用结束,这个方法中所有的局部变量也应该在内存中消失。
        ii. 对于对象而言,只要有引用指向一个对象,这个对象就不会变成垃圾。而匿名内部类本质就是一个对象,当方法的外部有其他引用指向这个对象的时候,哪怕其所在的方法调用完毕,这个对象也还会存在堆内存中。
        iii. 而作为匿名内部类中的方法,只要对象存在,这个方法就有可能被调用,而在上图所示的代码中,如果我们调用匿名内部类中的这个方法,就会要打印num变量值,但是如果方法已经调用完毕,num 这个变量是应该消失的。相当于            我们会用一个存在的对象调用方法去打印一个已经消失的变量。
        iv. 怎么办呢?接着往下看。
    d) 解决方案
        i. 其实作为代码编辑器的eclipse已经给了我们很友好的提示,解决方案其实很简单,就是定义变量num的时候用final修饰,使其成为一个常量,作为常量,其值是一直不会改变的。
        ii. 所以当方法调用完毕,num从内存中消失,我们再去调用匿名内部类中的方法打印num变量的时候,直接相当于打印一个常量100,程序的运行也不会受到影响。


5. 写在最后:
    a) 以后可能经常会在一些别人的代码中遇到匿名内部类,所以我们还是有必要把它掌握的。
    b) 以上就是对匿名内部类的讲解,你学会了吗?














作者: 钟佩桓    时间: 2017-10-21 22:33
6666不错啊
作者: wheat    时间: 2017-10-21 22:41
总结的到位

作者: Java程序员_风雨    时间: 2017-10-21 22:43
66666  什么书  什么堂!!!
作者: i19920412    时间: 2017-10-21 22:49
嗯哼,哎哟不错哦
作者: y244219411    时间: 2017-10-22 08:56
总结的很细,
作者: U g d d    时间: 2017-10-22 09:01
先赞赞赞赞
作者: 12782716    时间: 2017-10-22 14:03
支持技术贴,楼主幸苦




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2