Java内部类

一、局部内部类

定义在外部类的局部位置,比如方法体中,并且有类名。

本质依旧是类。

1、可以访问外部类的所有成员,包括私有成员。

2、不能添加修饰符。

因为它等价于一个局部变量,局部变量不能使用修饰符。

可以使用final修饰,局部变量可以使用final修饰。

3、作用域:

仅在定义它的方法体或代码块中。

4、局部内部类访问外部类成员:

直接访问

5、外部类访问局部内部类成员:

先创建对象,再访问。(注意,必须在作用域内)

6、外部其他类无法访问内部类,因为内部类只是一个局部变量。

7、如果外部类和局部内部类的成员重名,遵循就近原则。

若想访问外部类成员,使用 外部类名.this.成员 去访问。

原因:

外部类名.this 本质就是外部类的对象,该对象就是目前调用自己的外部类对象。

二、匿名内部类

匿名內部类定义在外部类的 局部位置,比如方法体中,并且 没有类名。
本质也是类。
①本质是类;②内部类;③没有名字(其实有,系统分配);④同时是一个对象。
语法:

java 复制代码
    new 类名或接口名(参数列表){
        类体
    }

经典使用场景:
当作实参传递,简洁高效。
一、基于接口:
需求:
需要使用一个接口,但是只使用一次。
正常情况:
(1)定义子类、(2) 重写接口中的方法、(3) 创建子类对象、(4) 调用重写后的方法
因为只使用一次,且定义后就使用,因此专门定义该类没有意义。
解决:
使用匿名内部类:

a1和a2的编译类型为A,运行类型为Outer1 和Outer2
在底层:

java 复制代码
    class Outer$1 implement A{
        public void fun() {
            System.out.println("匿名内部类");
        }
    }

①先如上代码定义一个实现了接口A的类。
②立刻创建一个该类的对象,并赋值给变量a1。
③之后无法使用Outer1创建新的对象了。 ④由上可见,匿名内部类命名规则是外部类名 + +阿拉伯数字(是第几个匿名内部类,就是几)。
二、基于类:
需求:
需要使用一个接口,但是只使用一次。
正常情况:
(1)定义子类、(2) 重写父类中的方法、(3) 创建子类对象、(4) 调用重写后的方法
因为只使用一次,且定义后就使用,因此专门定义该类没有意义。

在底层:

java 复制代码
class Outer03$1 extend Fater{
    @Override
    void fun() {
        System.out.println("重写fun()方法");
        newFun();
    }
    void newFun(){
        System.out.println("新方法");
    }
}

①先如上代码定义一个实现了继承了Father的类。
②立刻创建一个该类的对象,并赋值给变量father。
③new Father("tom"){};中的字符串"tom"将传递给Father这个父类的构造器。
如果父类是抽象类,那么对于抽象类中的抽象方法就必须实现。
细节:
1、可以直接访问外部类的所有成员,包括私有的。
2、不能添加访问修饰符,因为它的地位就是一个局部变量。
3、作用域:在定义它的方法内或代码块内。
4、匿名内部类没有构造方法,因为匿名内部类是没有类名的。
5、匿名内部类不能定义任何静态成员、方法。
匿名内部类是晚于外部类加载的。
匿名内部类和其对象几乎是同时加载的(但是还是早于对象加载)。
而静态内容是属于类的,当类加载的时候就开始加载。
所以当匿名内部类中有静态内容,就会随着类加载,而这时和对象创建冲突。

三、成员内部类

就是一个定义在外部类成员位置的类。

细节:

1、可以直接访问外部类的所有成员。

2、可以有任何修饰符,它本身就是一个成员。

3、外部其他类使用成员内部类:

由于内部类使用的目的就是它自身不会有多个对象,没必要专门在外面定义,

所以外部其他类使用成员内部类情况很少,如果使用一般会在外面定义。

①外部类.成员内部类 类名 = 外部类对象.new 成员内部类();

内部成员类首先是一个成员,通过外部类对象.形式调用

它又是一个类,所以要new。

②在外部类中写一个方法,返回成员内部类的对象。

四、静态内部类

定义在外部类的成员位置上,且有static修饰。

细节:

1、可以访问外部类的所有静态成员,包括私有的,但不能访问非静态的。

原因:由于是静态的,在外部类加载时就已经创建,但是外部类其他非静态成员

还未创建,类似静态方法。

2、可以添加任何修饰符。

3、外部其他类访问静态内部类:

①new 外部类名.静态内部类名();

因为是静态的,所以直接通过外部类名可以访问,不需要外部类的对象。

②写一个方法,返回内部类的实例。

相关推荐
戴西软件11 分钟前
戴西软件入选2026年安徽省制造业数智化转型服务商名单
java·大数据·服务器·前端·人工智能
爱棋笑谦12 分钟前
springboot—数据源相关配置
java·spring boot·spring
budingxiaomoli8 小时前
Spring IoC &DI
java·spring·ioc·di
Spider Cat 蜘蛛猫8 小时前
Springboot SSO系统设计文档
java·spring boot·后端
未若君雅裁9 小时前
MySQL高可用与扩展-主从复制读写分离分库分表
java·数据库·mysql
学习中.........9 小时前
从扰动函数的变化,感受红黑树带来的性能提升
java
计算机安禾9 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
weixin1997010801610 小时前
【保姆级教程】淘宝/天猫商品详情 API(item_get)接入指南:Python/Java/PHP 调用示例与 JSON 返回值解析
java·python·php
环流_10 小时前
redis核心数据类型在java中的操作
java·数据库·redis
雨辰AI10 小时前
SpringBoot3 项目国产化改造完整流程|从 MySQL 到人大金仓落地
java·数据库·后端·mysql·政务