• Java的四种内部类


    成员内部类

      * 定义在另一个类(外部类)的内部,而且与成员方法和属性平级叫成员内部类,......相当于外部类的非静态方法,
        如果被static修饰,就变成静态内部类了。
      * 注意事项:
            1. 成员内部类中不能存在static关键字,即,不能声明静态属性、静态方法、静态代码块等。【非静态内部类
               也可以定义静态成员但需要同时有final关键词修饰,静态方法鉴于无法用final修饰,仍必须是在静态内部类 
               或者非内部类中定义。】
            2.创建成员内部类的实例使用:外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数),可以理
              解为隐式地保存了一个引用,指向创建它的外部类对象。
            3.在成员内部类中访问外部类的成员方法和属性时使用:外部类名.this.成员方法/属性。
            4.内部类在编译之后生成一个单独的class文件,里面包含该类的定义,所以内部类中定义的方法和变量可以跟父类
              的方法和变量相同。例如上面定义的三个类的class文件分别是:MyTest.class、Outer.class和Outer$Inner.class三个文件。
            5.外部类无法直接访问成员内部类的方法和属性,需要通过内部类的一个实例来访问。
            6.与外部类平级的类继承内部类时,其构造方法中需要传入父类的实例对象。且在构造方法的第一句调用“外部类实例名.super(内部类参数)”。
      * 实例:
            //成员内部类......相当于非静态方法
            class Outer{
                private int a = 3;
                private Inner in;
                public Outer(){
                    in = new Inner();
                }
                public int getInnerA(){
                    return in.a;  // 引用内部类的变量,需通过实例
                }
            public class Inner {
                    public int a = 2;
                    public void doSomething() {
                        // 调用外部类的属性
                        System.out.println(MemberInner.this.a);// 这块要注意......很重要!!!
                        System.out.println(a);
                    }
           }
      }
    
      public class Test3 {
          public static void main(String[] args) {
              Outer.Inner inner = new Outer().new Inner();// 非静态内部类要new实例
              inner.doSomething();
          }
      }
    
      class Extender extends Outer.Inner{  
          public Extender(Outer outer){  
             //外部类实例名.super(内部类参数列表)  
             outer.super();  
          }  
      }
    

    静态内部类

      * 使用static修饰的成员内部类叫静态内部类。
        可以这样理解:与外部类同级的类,或者叫做外部类的静态成员。与成员内部类的对比如下:
    
    说明 成员内部类 静态内部类
    静态成员 静态成员需同时有final关键词修饰 可以
    静态方法 不可定义 可以
    访问外部类非static属性/方法 外部类名.this.成员方法/属性 不可以
    外部类访问内部类 需要通过内部类的一个实例来访问 需要通过内部类的一个实例来访问
    创建实例 外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数) 外部类名.内部类名 实例名 = new 外部类名.内部类名(参数)
    编译后的class文件 单独的class文件(so内部类中的方法和变量可以跟父类的方法和变量同名),外部类$内部类.class 单独的class文件(so内部类中的方法和变量可以跟父类的方法和变量同名),外部类$内部类.class
    其他 与外部类平级的类继承内部类时,其构造方法中需要传入父类的实例对象。且在构造方法的第一句调用“外部类实例名.super(内部类参数)”

    局部内部类

      * 定义在代码块、方法体内、作用域(使用花括号“{}”括起来的一段代码)内的类叫局部内部类。
            1.局部内部类只能在代码代码块、方法体内和作用域中使用(如创建对象和使用类对象等)
            2.局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰。
            3.可以使用abstract修饰,声明为抽象类。
    

    匿名内部类

      * 匿名内部类定义和实例化形式如下: 
            new 父类构造方法(参数){ 
                 //注:该方法名必须在父类中已经存在 
                 修饰符 返回参数类型 方法名(参数列表){ 
                 。。。
                 } 
            }
      1.只能使用一次,创建实例之后,类定义会立即消失(想要多次使用就要用到反射的知识了)
      2.必须继承一个类(抽象的、非抽象的都可以)或者实现一个接口。如果父类(或者父接口)是抽象类,则匿名内部类必须实现其所有抽象方法。
      3.不能是抽象类,因为匿名内部类在定义之后,会立即创建一个实例。
      4.不能定义构造方法,匿名内部类没有类名,无法定义构造方法,但是,匿名内部类拥有与父类相同的所有构造方法。
      5.可以定义代码块,用于实例的初始化,但是不能定义静态代码块。
      6.可以定义新的方法和属性(不能使用static修饰),但是无法显式的通过“实例名.方法名(参数)”的形式调用,因为使用new创建的是“上转型对象”
       (即父类声明指向子类对象)。
      7.是局部内部类,所以要符合局部内部类的要求。
    
    说明 成员内部类 匿名内部类
    静态成员 静态成员需同时有final关键词修饰 不可定义
    不可定义 不可定义
    访问外部类非static属性/方法 外部类名.this.成员方法/属性 外部类名.this.成员方法/属性
    外部类访问内部类 需要通过内部类的一个实例来访问 需要通过内部类的一个实例来访问
    创建实例 外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数) 如上:父类 实例名 = new 父类(){}
    编译后的class文件 单独的class文件(so内部类中的方法和变量可以跟父类的方法和变量同名),外部类$内部类.class 单独的class文件,使用类$数字.class
    其他 与外部类平级的类继承内部类时,其构造方法中需要传入父类的实例对象。且在构造方法的第一句调用“外部类实例名.super(内部类参数)”
      * 原文链接:https://www.cnblogs.com/dorothychai/p/6007709.html
  • 相关阅读:
    在Excel中查找/替换时使用换行符
    用fieldset标签轻松实现Tab选项卡效果
    用JSFL将Flash中的元件导出为PNG
    PHP学习笔记之PDO
    网页中的数学公式
    解决fl.findObjectInDocByType/fl.findObjectInDocByName的毛病
    HTML+CSS 网页中鼠标滚轮失效的解决办法
    jQuery 离开页面时提示
    ASP 计算出指定年份生肖
    au3创建Access数据库表例子
  • 原文地址:https://www.cnblogs.com/ITHSZ/p/13223901.html
Copyright © 2020-2023  润新知