• 【学习笔记】 唐大仕—Java程序设计 第5讲 深入理解Java语言之5.5 内部类与匿名类


    /**
    * 内部类与匿名类
    * @author cnRicky
    * @date 2018.11.10
    */
    内部类与匿名类
    • 内部类(inner class)是在其他类中的类
    • 匿名类(anonymous class)是一种特殊的内部类,它没有类名
    内部类(Inner class)
    • 内部类的定义

      • 将类的定义class xxxx{...}置入一个类的内部即可
      • 编译器生成xxxx$xxxx这样的class文件
      • 内部类不能够与外部类同名
    • 内部类的使用

      • 在封装它的内的内部使用内部类,与普通的使用方式相同
      • 在其他地方使用
        • 类名前要冠以外部类的名字
        • 在用new创建内部类时,也要在new前面冠以对象变量
        • 外部对象名.new 内部类名(参数)
    class TestInnerClass{
        public static void main( String[] args ){
            Parcel p = new Parcel();
            p.testShip();
    
            Parcel.Contents c = p.new Contents(33);
            Parcel.Destination d = p.new Destination( "Hawii" );
            p.setProperty( c, d );
            p.ship();
        }
    }
    
    class Parcel {
      private Contents c;
      private Destination d;
      class Contents {
        private int i;
        Contents( int i ){ this.i = i; }
        int value() { return i; }
      }
      class Destination {
        private String label;
        Destination(String whereTo) {label = whereTo;}
        String readLabel() { return label; }
      }
      void setProperty( Contents c, Destination d ){
        this.c =c; this.d = d;
      }
      void ship(){
        System.out.println( "move "+ c.value() +" to "+ d.readLabel() );
      }
      public void testShip() {
        c = new Contents(22);
        d = new Destination("Beijing");
        ship();
      }
    }
    在内部类中使用外部类的成员
    • 内部类中可以直接访问外部类的字段及方法

      • 即使private也可以
    • 如果内部类中有与外部类同名的字段或方法,则可以用

      • 外部类名.this.字段及方法
    • 例子:

    class A
    {
        private int s = 111;
        
        public class B{
            private int s = 222;
            public void mb(int s){
                System.out.println(s);//局部变量s
                System.out.println(this.s);//内部类对象的属性s
                System.out.println(A.this.s);//外层类对象属性s
            }
        }
    }
    内部类的修饰符
    • 内部类与类中的字段、方法一样是外部类的成员,它的前面也可以有访问控制符和其他修饰符
      • 访问控制符:public、protected,默认(default)及private
        • 注:外部类只能够使用public修饰或者默认
      • final,abstract
    static修饰符
    • 用static修饰内部类,表名该内部类实际是一种外部类

      • 因为它与外部类的实例无关
      • 有人认为static的类是嵌套类(nested class),不是内部类(inner class)
    • static类在使用时:

      • 1、实例化static类时,在new前面不需要用对象实例变量;
      • 2、static类中不能访问其外部类的非static的字段及方法,即只能够访问static成员
      • 3、static方法中不能访问非static的域及方法,也不能够不带前缀地new一个非static的内部类
    • 例子:

    public class TestInnerStatic
    {
        public static void main(String[] args)
        {
            A.B a_b = new A().new B();//ok
            A a = new A();
            A.B ab = a.new B();
            
            Outer.Inner oi = new Outer.Inner();
            //Outer.Inner oi2 = new Outer.new Inner();//!!!error
            //Outer.Inner oi3 = new Outer().new Inner();//!!!error
        }
    }
    
    class A
    {
        private int x;
        void m(){
            new B();
        }
        static void sm(){
            //new B();//error!!!
        }
        class B
        {
            B(){ x = 5; }
        }
    }
    class Outer
    {
        static class Inner
        {
            
        }
    }
    局部类
    • 在一个方法中也可以定义类,这种类称为“方法中的内部类”
    • 或者叫局部类(local class)
    • 例子:
    class TestInnerInMethod
    {
        public static void main(String[] args)
        {
            Object obj = new Outer().makeTheInner(47);
            System.out.println("Hello World!" + obj.toString());
        }
    }
    
    class Outer
    {
        private int size = 5;
        public Object makeTheInner(int localVar)
        {
            final int finalLocalVar = 99;
            class Inner{
                public String toString(){
                    return("InnerSize:" + size +
                          // "localVar:" + localVar + //Error!
                           "finalLocalVar:" + finalLocalVar
                          );
                }
            }
            return new Inner();
        }
    }
    使用局部类
    • 1、同局部变量一样,方法中的内部类

      • 不能够用public,private,protected,static修饰
      • 但可以被final或者abstract修饰
    • 2、可以访问其外部类的成员

    • 3、不能够访问该方法的局部变量,除非是final局部变量

    匿名类
    • 匿名类(anonymous class)是一种特殊的内部类

      • 它没有类名,在定义类的同时就生成该对象的一个实例
      • “一次性使用”的类
    • 例子:

    class TestInnerAnonymous
    {
        public static void main(String[] args) 
        {
            
        }
    }
    
    class Outer
    {
        private int size = 5;
        public Object makeTheInner(int localVar)
        {
            final int finalLocalVar = 99;
            return new Object(){
                public String toString(){
                    return ("InnerSize:" + size + "finalLocalVar:" + finalLocalVar);
                }
            };
        }
    }
    匿名类的使用
    • 1、不取名字,直接用其父类或接口的名字

      • 也就是说,该类是父类的子类,或者实现了一个接口
      • 编译器生成xxxxx$之类的名字
    • 2、类的定义的同时就创建实例,即类的定义前面有一个new

      • new 类名或接口名(){ ...... }
      • 不使用关键字class,也不使用extends及implements
    • 3、在构造对象时使用父类构造方法

      • 不能够定义匿名类的构造方法,因为它没有名字
      • 如果new对象时,要带参数,则使用父类的构造方法
    匿名类的应用
    • 用到界面的事件处理
      • 注册一个事件监听器
      • 示例AutoScore.java中
    //SymAction ISymAction = new SymAction();
    //btnNew.addActionListener(ISymAction);
    
    btnNew.addActionListener(new ActionListener(){
       public void actionPerformed(ActionEvent event)
       {
           ......;
       }
    });
    • 作为方法的参数
      • 排序,给一个比较大小的接口
      • 如:
    Arrays.<Book>sort(books, new Comparator<Book>(){
        public int compare(Book b1, Book b1){
            return b1.getPrice()-b2.getPrice();
        } 
    });
  • 相关阅读:
    SQL中如何用一个表的列更新另一个表的列?
    ASPxGridView利用CheckBox实现全选
    DevExpress.NETv8.1(Web Controls)学习笔记
    ALSA vs OSS
    video telephone
    uClinux系统分析 转
    Using KVM On Ubuntu 7.10 (Gutsy Gibbon)转
    想买开发板,我真的需要么?
    uClinux的内存管理转
    各种开源软件授权方式的选择 (zt)
  • 原文地址:https://www.cnblogs.com/dreamcoding/p/9940536.html
Copyright © 2020-2023  润新知