黑马程序员:Java培训、Android培训、iOS培训、.Net培训

                     黑马程序员--JAVA内部类

一、内部类分为显式内部类和匿名内部类。

二、显式内部类

    1、即显式声明的内部类,它有类名。

    2、显式内部类分为:普通显式内部类、嵌套类、局部显式内部类。

    3、普通显式内部类

       1)在外围类体中声明的内部类,是其外围类的一部分。

       2)(public)class Outer{

              ……..

              class Inner{ ………}

              ……..

           }

       3) 普通显式内部类不能有static数据和static方法。

       4)可通过外部类的普通方法返回普通显式内部类对象的引用。

       5)普通显式内部类拥有其外部类的所有元素的访问权。

       6)this 与 new

       7) 迭代器设计(模式)

    4、嵌套类

       1)将普通显式内部类声明为static.

       2)  (public) class Outer{

                …….

                private static class Inner{ ……..}

                ……..

           }

       3)为什么使用嵌套类?

              不需要内部类对象与其外围类对象间有联系,即嵌套类对象与其外围类对象无关。这就意味:(1)创建嵌套类对象不需要使用其外围类对象;(2)不能从嵌套类对象中访问非静态的外部类数据和方法。

       4)可通过外部类的静态方法返回嵌套类的引用。

    5、局部内部类

       1)在代码块内(例如:方法体内)创建的内部类。

       2)下面的代码实现如何返回局部内部类对象的引用

           (public) class Outer{

                ……..

                Father father = null;

                Father method(){

                    …….

                    class Inner extend Father{……..}

                    …….

                    Inner in = new Inner();

                    return in;     

                }

           }

           //如果不需要返回局部内部类的引用,则不需要任何继承或实现接口

       3) 局部内部类不是其外部类的一部分,但,它可以访问当前代码块内的常量及其外部类的所有成员。

       4)局部内部类在其作用域外不可见。

 三、匿名内部类

   1、匿名内部类是显式普通内部类的声明和返回其引用的外部函数的简化形式。

   2、使用匿名内部类实现一个接口。

   3、匿名内部类继承其父类并返回其引用。

          (public)class Outer{

                ……

                public Father method(){

                   ……

                   //匿名内部类

                   return new Father(){……….};

                }

                …….

            }

    4、使用匿名内部类扩展带有非默认构造器的类。

           (public)class Outer{

                …….

                Public Father method(int arg){

                    //匿名内部类

                    return new Father(arg){ ……… };

                }

                ……..

            }

     5、在匿名内部类体内添加字段并初始化。

           (public)class Outer{

                 …...

                 public Father method(final int arg){

                     ……

                     return new Father(){

                         private int field = arg;

                         …….

                     };

                 }

                 ……

             }

         //方法传递的参数是给匿名内部类直接使用,而不是给其父类使用的,应当声明

//为final

    6、实例初始化

        匿名内部类不可能有命名构造器,如何能够达到为匿名内部类创建一个构造器的效果,这就是实例初始化的作用。这是通过使用实例初始化块来实现的。

           (public)class Outer{

                …….

                Public Father method(int arg){

                    //匿名内部类

                    return new Father(arg){

 ………

     {//实例初始化块

       ………

     }

     ………..

 };

                }

                ……..

            }

 

四、其他需要注意的问题

   1、外部类子类的内部类不会覆盖外部类的内部类。因为外部类的内部类和外部类子类的内部类是完全独立的两个实体,各自在自己的命名空间内。

   2、如何直接使用内部类?

        Outer.Inner in = Outer.new Inner();

   3、如何继承内部类?

        class InnerSum extends Outer.Inner{

            …….

        }

   4、匿名内部只能够实现一个接口,并且只能扩展类,或者实现接口,不能两者兼备。