什么时候使用内部类?

     徐老师举了个例子:奔驰的发动机的特点就是只能给奔驰的汽车使用,虽然他也是发动机

但是别人用不了,这样就可以把奔驰的发动机定义为奔驰的内部类.内部类的特点就是只有包含

他的类才能访问 对外是不公开的.

    定义: 将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)

    访问特点:

        1.内部类可以直接访问外部类中的成员,包括私有成员.

        2.而外部类要访问内部类中的成员必须要建立内部类对象.


内部类的位置

   内部类定义在成员位置上(与类的属性和方法同级)

         1. 可以被private static 成员修饰符修饰

         2.被static修饰的内部类只能访问外部类中的静态成员

    内部类定义在局部位置上(在类方法的)

          1.也可以直接访问外部类中的成员

          2.同时可以访问所在局部中的局部变量或类的成员属性,但必须是被final修饰的.


为什么在局部位置的内部类中访问的成员必须是final的?

    一个方法也许是复杂的,在这个复杂的方法内部增加一个内部类,这个内部类中还会有其他的方法,如果方法很复杂,

层次很深的话,那么内部类如果对同级别的局部变量进行修改 那么对于外部变量调试起来是很困难的.比如我忘了这个变量

不需要进行修改,但是我在内部类的方法中不小心给修改掉了,然后再调试的时候编写代码的人很难想到是内部类中的什么

方法修改这个变量.所以最好的办法就是在局部位置的内部类中不允许修改与其同级别的局部变量.


匿名内部类

    是内部类的简化写法,将对类的继承,方法重写,对象的创建 这三个步骤用一行代码完成

    前提:

        内部类可以继承或实现一个外部类或者接口.

    格式为:

        new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容.)}

    简单理解:

        就是建立一个带内容的外部类或者接口的子类匿名对象.


--------------------以下是对匿名内部类的个人理解-------------------------


匿名内部类就是将抽象类中的所有抽象方法实现,并将其实例化.比如下面有一个抽象类

   

abstract class Benz implements Runable{

}

interface Runable

{

    public void run();

}

抽象类实现了Runable接口 但是并没有对具体的类进行实现 如果我们这个时候调用 new Benz 肯定是要报错的.

所以为了实例化抽象的 Benz类 首先要实现Runable接口中定义的方法.

class Main

{

    public static void main(String args[]){

        Runable b=new Benz(){public void run(){System.out.println("run");}};

        b.run();

    }

}

new Benz(){....} 表示创建了一个新的匿名类继承了Benz 类,而且这个类将接口方法实现了,就可以实例化了.

再来看一个例子

    在第四节 我记录了适配器模式的实现方法.以一个按钮为例子.比如一个按钮有很多种调用方式,单击,双击等等....

单击,双击 这些方法都是行为,我们将其封装在ButtonListener这个接口中,并创建了ButtonListenerAdapter

这个抽象的适配器 实现了 ButtonListener接口 将其中不长使用的 方式进行了空实现,而把我们的注意力放在

单击方法的实现上.如果想使用单击方法就要创建一个 myListener 继承适配器 并将其中没有被实现的单击方法

进行具体实现.

    但是这个过程太麻烦 我们想要使用按钮的单击就必须创建 myListener 继承 ButtonListenerAdapter类 ,

可以直接实例化 ButtonListenerAdapter吗,然后直接调用其中的单击方法. 结果是不行的,因为ButtonListener类是抽象的, 

想想怎么实例化抽象类? 我们可以使用匿名内部类对象.现在就可以这么写

    Button btn = new Button();

    btn.addListener(new ButtonListenerAdapter(){

        public void click(){System.out.println("单击实现");}

    });

    btn.click();

    

    这样我们在匿名的ButtonListenerAdapter的子类中实现了抽象方法,并将其实例化设置给Button对象供其使用.