• Java学习笔记19---内部类之简介成员内部类、局部内部类及匿名内部类


    内部类,顾名思义,即定义在某个类内部的类,称包含该内部类的类为外部类。

    从定义的位置来说,分为成员内部类和局部内部类;从类的特征来说,分为匿名内部类和静态内部类。

    今天先简要介绍一下前三种内部类的定义及简单使用。

     如需转载请注明出处,谢谢:

    http://www.cnblogs.com/chanchan/p/8235169.html 

    1.成员内部类

    成员内部类可看成外部类的一个成员,定义的位置与外部类的其他成员一样,只不过它是个类而已。

    示例:

    类Person中定义了一个成员内部类InnerClass,具体如下:

        private String hobby;   
         //笔记19:内部类--成员内部类
        class InnerClass {
            String name;
            
            void printInC() {
                System.out.println("inner class");
            }
            
            void printPriVar() {
                System.out.println("hobby:" + hobby);
            }
        }
        //
    
        public static void main(String[] args) {
            
            Person per = new Person();
            
            //笔记19:内部类--成员内部类
            Person.InnerClass inC = per.new InnerClass();
            inC.printInC();
            inC.printPriVar();
    }

    输出结果为:

    inner class
    hobby:null

    分析:

    (1).成员内部类可以访问外部类的private成员,当然也可以访问其他权限的成员;

         也可以由访问权限修饰符来修饰。

    (2).Person.InnerClass inC = per.new InnerClass();

        该行定义了一个内部类的对象inC,可推知:

          1>.成员内部类的类型为 外部类名.内部类名

          2>.创建成员内部类对象时,要先创建一个外部类对象,再由该外部类对象使用.new来创建内部类对象;

               即,成员内部类是依附于外部类的,必须由一个外部类的实例来完成对内部类对象的创建;

               从这里也能理解为什么可以把成员内部类看成外部类的一个成员:一个类的非静态成员必须等创建类的实例后才会分配空间,成员内部类也类似。

    2.局部内部类

    局部内部类是定义在方法体与作用域内的内部类,可与局部变量类比。

    示例:

    类Person的成员方法localInClass中定义了一个内部类LoInnerClass,具体如下:

        //笔记19:内部类--局部内部类
        public void localInClass() {
            class LoInnerClass {
                void printLI() {
                    System.out.println("local inner class");
                }
            }
            LoInnerClass lInC = new LoInnerClass();
            lInC.printLI();
        }
        //
    
        public static void main(String[] args) {
            
            Person per = new Person();
            
            //笔记19:内部类--局部内部类
            per.localInClass();
    }

    输出结果为:

    local inner class

    分析:

    (1).局部内部类的作用域为定义它的方法体内,其他地方不可见,同局部变量。

    (2).局部内部类不可以由访问权限修饰符修饰;既然其作用域只在方法体内,由访问权限修饰符修饰也没什么意义。

    (3).局部内部类对象的创建不依赖于外部类,同一般类。

    前面两种内部类是从定义位置来划分的,成员内部类可看成类的成员,局部内部类可看成局部变量。这两种类都有名有姓,与一般类还比较相似,只是定义位置比较特殊。下面要说的匿名内部类就更特殊,它连名字都没有,来看看具体怎么操作吧。

    3.匿名内部类

    匿名内部类属于局部内部类,可以作为返回值或参数,直接看示例比较直观。

    示例中的AnoInnerClass是一个接口,代码如下:

    package human;
    
    public interface AnoInnerClass {
        void printAnoI();
    }

    示例1:作为返回值

     1     //笔记19:内部类--匿名内部类--作为返回值
     2     public AnoInnerClass anonymousClass() {
     3         return new AnoInnerClass () {
     4             public void printAnoI() {
     5                 System.out.println("anonymous inner class:return value");
     6             }
     7         };
     8     }
     9 
    10     public static void main(String[] args) {
    11         
    12         Person per = new Person();
    13         
    14         //笔记19:内部类--匿名内部类--作为返回值
    15         AnoInnerClass anoInC = per.anonymousClass();
    16         anoInC.printAnoI();
    17 }

    输出结果为:

    anonymous inner class:return value

    分析:

    (1).先来看12和15行,12行创建一个Person类的对象per,15行定义AnoInnerClass类型的对象引用anoInC,并指向了per调用anonymousClass后的返回值;

          成员方法anonymousClass的返回值是AnoInnerClass类型,由于AnoInnerClass类型是接口,是无法实例化的,所以返回的值必须是某个实现了该接口的类的实例,这里,这个实现了接口AnoInnerClass的类就是匿名内部类,参见3-7行;

          该匿名内部类的具体内容就跟在new AnoInnerClass()后面,以{}括起来;

    (2).这里还涉及到向上转型的问题

          由于匿名内部类没有类名,所以第2行返回值的类型也是写得内部类的父类接口AnoInnerClass,实际返回的是匿名内部类的实例,把该实例赋给了父类的对象引用。

    示例2:作为参数

     1     //笔记19:内部类--匿名内部类--作为参数--重载
     2     public void anonymousClass( AnoInnerClass anoInC ){
     3         anoInC.printAnoI();
     4     }
     5     //
     6 
     7     public static void main(String[] args) {
     8         
     9         Person per = new Person();
    10         
    11         //笔记19:内部类--匿名内部类--作为参数--重载
    12         per.anonymousClass(new AnoInnerClass() {
    13             public void printAnoI() {
    14                 System.out.println("anonymous inner class:argument");
    15             }
    16         });
    17 }

    输出结果为:

    anonymous inner class:argument

    分析:

    (1).与示例1不同的是,匿名内部类作为参数时,是在实际调用时实现的,也就是说匿名内部类是实参。

    (2).其他地方与示例1大同小异。

    从示例1和示例2也可以看出来,匿名内部类是属于局部内部类的。

    匿名内部类没有名字,它必须要继承一个父类或实现一个接口,且只能继承或实现一个父类或接口;否则作为返回值时,返回值类型就不知道怎么表示了,作为参数时,参数类型也没法表示了。

    PS:

    这段时间确实有点事情,但主要是懒癌发作,拖了1个月才找回状态,实在惭愧!!!

  • 相关阅读:
    MSDN for 2010的那些麻烦事
    CPtrList操作--插入,删除特定元素,删除全部
    如何绕过ORA00701错误和降低bootstrap对象的高水位
    ORA00600:[1112]内部错误&ROW CACHE ENQUEUE LOCK一例
    CRS5008: Invalid attribute value
    ORA00600[kjpsod1]&ORA44203错误一例
    runInstaller ignoreInternalDriverError
    RMAN CURSOR_SHARING=EXACT脚本
    SQL调优:带函数的谓词导致CBO Cardinality计算误差
    11g Real Application Testing:Database Replay使用方法
  • 原文地址:https://www.cnblogs.com/chanchan/p/8235169.html
Copyright © 2020-2023  润新知