JAVA内部类

当一个事物 A 的内部,还有一个部分需要一个完整的结构 B 进行描述,而这个内部的完整的结构 B 又为外部事物 A 提供服务,不在其他地方单独使用,那么整个内部的完整结构 B 最好使用内部类。颇有细胞,组织,器官,系统,个体,种群,群落,生态系统,生物圈的感觉了。一层又一层的封装。遵循高内聚、低耦合的面向对象开发原则。该隐藏的隐藏,该暴露的暴露。

内部类,在类里边。那是和属性们待在一起还是和方法们待在一起?

所以有成员内部类和局部内部类的区分。

成员内部类

因为作为类的一部分存在,所以也会有和类绑定的情况,此时static也可以修饰内部类(注:仅限内部类,外部类不可以哦)

所以划分为静态成员内部类和非静态成员内部类。

(1)作为属性,作为类中的成员:可以声明为 private 或 protected(毕竟此时只算一个属性,有private可以隐藏一部分信息),可以调用外部类的结构。(注意:在静态内部类中不能使用外部类的非静态成员)
(2)作为类的角色:可以在内部定义属性、方法、构造器、代码块、内部类等结构;可以继承自己想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关;可以声明为 abstract 类 ,可以被其它的内部类继承;可以声明为 final 表示不能被继承;编译以后生成OuterClass$InnerClass.class 字节码文件(也适用于局部内部类)。从这一点来说,内部类使得类可以继承多个具体类或抽象类。

外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
• 成员内部类可以直接使用外部类的所有成员,包括私有的数据
• 当想要在外部类的静态成员部分使用内部类时,可以考虑声明内部类为静态的
• 在内部类中调用外部类的结构时,不重名可以直接调,重名之后就近原则,name -- this.name -- person.this.name

静态成员内部类

静态内部类不能再使用外层类的非 static 的成员变量;
被 static 修饰的内部类可以直接作为一个普通类来使用,不需要实例化一个外部类。
实例化静态内部类:

外部类名.静态内部类名 变量 = 外部类名.静态内部类名();
变量.非静态方法();

那么静态内部类可不可以定义非静态方法呢?当然可以,只是变出非静态的东西后,必须创建对象才能调用(普通方法是属于对象的)。(因为在调的时候没有对象不知道调的到底是什么,这也是静态和非静态最大的区别:一个随类加载,一个没有。在不确定时,没法一起合作。)

非静态成员内部类

非静态内部类可以访问外部类的所有成员(方法、属性);
类似的,不被 static 修饰的内部类则需要实例化一个外部类。
实例化非静态内部类:

外部类名 变量 1 = new 外部类();
外部类名.非静态内部类名 变量 2 = 变量 1.new 非静态内部类名();
变量 2.非静态方法();

参考链接:https://blog.csdn.net/zuo_er_lyf/article/details/103488246

局部内部类

局部内部类,就是放在类的方法、构造器、代码块里的一个类,这个类是为这些方法等服务的,作用域小,是不是一定要有名字呢?
所以有匿名局部内部类和非匿名局部内部类的区分。

开发中一般见到的是调用的方法需要返回接口的实例,需要提供实现接口的类,返回实现接口类的对象。
一般常看见的代码有提供接口的实现类的对象、接口的实现类的匿名对象、接口的匿名实现类的对象和接口的匿名实现类的匿名对象。

编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名、$符号、编号(有编号是因为同一个外部类中,不同的方法中存在相同名称的局部内部类)。
• 和成员内部类不同的是,它前面不能有权限修饰符等
• 局部内部类和局部变量一样,有作用域
• 局部内部类中是否能访问外部类的非静态的成员,取决于所在的方法

匿名内部类

匿名类可以实现接口,也可以继承类,具体取决于你的需求。

  1. 实现接口:当你想要创建一个匿名类来实现一个接口时,你可以在new关键字后面指定接口名,然后在匿名类的内部实现接口的方法
MyInterface myInterface = new MyInterface() {
    @Override
    public void doSomething() {
        // 实现接口方法的代码
    }
};
  1. 继承类:你也可以创建一个匿名类来继承一个现有的类,而不仅仅是实现接口。在这种情况下,你需要在new关键字后面指定要继承的类名,并在匿名类的内部可以重写父类的方法或添加自己的方法
MyClass myClass = new MyClass() {
    @Override
    public void someMethod() {
        // 重写父类方法的代码
    }

    public void additionalMethod() {
        // 添加自己的方法
    }
};

感觉像是带着已有的信息,不给新东西起名字,下边直接写重写或继承的方法和新东西。

posted @ 2023-08-16 09:19  芋圆院长  阅读(5)  评论(0编辑  收藏  举报