• [14] 内部类



    1、内部类

    什么是内部类,定义在其他类中的类称之为内部类。内部类也可以有访问权限修饰符,甚至可以标记为abstract或final。内部类与外部类实例有特殊的关系,这种关系即允许内部类访问外部类的程序,也包括私有成员

    内部类分为下面四种:
    • 成员内部类
    • 局部内部类
    • 匿名内部类
    • 静态内部类

    1.1 成员内部类

    正如其名,内部类声明在某个类中,如果要实例化一个内部类实例,需要一个外部类的实例作为依托,内部类的实例只能通过外部类的实例来访问
    • 不能存在static的变量和方法
    • 必须先创建外部类才能创建内部类
    • 普通类只有public可用修饰符,但是内部类可以使用private和protected
    public class Demo { 
    
        private int value = 1;
        
        public class InnerDemo {
            public void seeOuterValue() {
                System.out.println("Value is:" + value);
            }
        }
        
    }
    public class Test {
        public static void main(String[] args) {
            Demo.InnerDemo inner = new Demo().new InnerDemo();
            inner.seeOuterValue();
        }
    }

    1.2 局部内部类

    局部内部类被定义在外部类的方法中,我们说,内部类必须依托于内部类,这就意味着对于局部内部类来说:
    • 如果想使用这个局部内部类,那么你必须在这个方法中实例化这个内部类
    • 只有abstract和final可以修饰局部内部类
    • 方法的局部变量为final或参数是effectively final,局部内部类才能使用

    当变量或参数在初始化之后,值再也没改变过,则说明其为effectively final
    public class Demo {
        private int value = 1;
    
        public void doSth() {
            //局部内部类
            class InnerDemo {
                public void seeOuterValue() {
                    System.out.println("Value is:" + value);
                }
            }
            //在方法体中实例化,才能使用局部内部类
            InnerDemo inner = new InnerDemo();
            inner.seeOuterValue();
        }
    
    }
    public class Test {
        public static void main(String[] args) {
            Demo demo = new Demo();
            demo.doSth();
        }
    }

    为什么必须是final或effectively final,因为从表面上看这些变量是同一个东西,实际上在编译时外部类和内部类是两个class文件,也就是说两者是独立的。内部类并不是直接调用方法传递的参数,而是利用自身的构造函数对传入的参数进行了备份,也就是实际上是调用的自身属性,其值是从外部参数拷贝过来的。那么假如不是final,方法参数发生了变化,而内部类的属性还是原来的值,显然是不合理的,因为在我们眼里,他们俩是一个整体,为了避免出现这种情况,就使用final来让该引用的参数不可变。

    1.3 匿名内部类

    从学习以来不论是知识点还是面试常见的问题,总会问到诸如接口和抽象类可以被实例化吗?显然是不能。很多时候我们采用的new然后直接跟接口或抽象类的形式,这又算什么呢?这就是匿名内部类
    • 没有名字(表面上似乎有名字,但那并不是它们的名字,定义时直接创建该类的对象)
    • 只能被实例化一次(无法重复使用)
      • 创建匿名内部类时会立即创建一个该类的实例,该类的定义会立即消失
      • 匿名内部类没有类名,无法“new 类名”来声明新的对象,所以就当前这一次
      • 没有名字和只能实例化一次,我仍然有点迷糊
    • 通常被申明在方法或代码块的内部
    • 没有构造函数
    • 不能是静态static的,也不能包括静态变量和方法
    • 匿名内部类也是一种局部内部类,所以局部内部类的显示对匿名内部类适用

    匿名类相当于在定义类的同时再新建这个类的实例。一个匿名类的创建有下面几个部分:
    • new:操作符
    • 接口名:或抽象类/普通类
    • () :这个括号表示构造函数的参数列表,接口没有构造函数所以一般填写空括号
    • {...}:大括号中间代码表示类的内部结构,也可以定义变量方法等,和普通类一样

    public abstract class Animal {
        public abstract void run();
    }
    public class Test {
        public static void main(String[] args) {
    
            Animal animal = new Animal() {
                @Override
                public void run() {
                    System.out.println("run!");
                }
            };
    
            animal.run();
        }
    }

    内部类是可以有构造方法的,但由于匿名内部类的特殊性,其没有构造函数!那么很多初始化工作我们如何完成?使用代码块
    public class Test {
        public static void main(String[] args) {
    
            Animal animal = new Animal() {
                {
                    System.out.println("start init");
    
                }
    
                @Override
                public void run() {
                    System.out.println("run!");
                }
            };
    
            animal.run();
        }
    }

    1.4 静态内部类(嵌套内部类)

    使用static修饰的内部类就是静态内部类,那么:
    • 创建不再依托于外部类
    • 不能使用外部类的非static成员变量和方法

    (感觉和静态方法差不多)


    2、小结

    成员内部类:
    • 必须有外部类作为依托
    • 不能有static变量和方法
    • 可以由private和protected修饰

    局部内部类:
    • 在方法中实例化后才能使用
    • 方法局部变量必须是final

    匿名内部类:
    • 不能有static变量和方法
    • 没有名字,只能使用一次
    • 没有构造函数
    • 方法变量必须是final

    静态内部类:
    • 和静态方法差不多
    • 不再依托外部类
    • 不能使用外部类的非静态成员变量和方法


    3、参考链接



  • 相关阅读:
    pl/sql developer中如何导出oracle数据库结构? 参考文章一
    ORACLE知识点整理之一
    WebService之第一天
    Eclipse中,open declaration;open implementation;open super implementation的区别
    Maven 手动添加 JAR 包到本地仓库
    clipse maven 项目 出现红色叹号 解决方法
    eclipse快捷键设置
    Hibernate3--快速入门--第一天
    C++ 虚函数表解析
    c++ primer复习(二)
  • 原文地址:https://www.cnblogs.com/deng-cc/p/8192258.html
Copyright © 2020-2023  润新知