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 外部类名.静态内部类名();

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

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

相关推荐
小李不想说话3 分钟前
HTTPS 加密原理
java·网络·网络协议·学习·安全·http·https
斯密码赛我是美女6 分钟前
ssti刷刷刷
java·服务器·前端
进击的小白菜1 小时前
Java回溯算法解决非递减子序列问题(LeetCode 491)的深度解析
java·算法·leetcode
众乐乐_20081 小时前
Java 后端给前端传Long值,精度丢失的问题与解决
java·前端·状态模式
北辰浮光1 小时前
[springboot]SSM日期数据转换易见问题
java·spring boot·后端
木梓辛铭1 小时前
Spring Cache的详细使用
java·后端·spring
招风的黑耳1 小时前
Java视频流RTMP/RTSP协议解析与实战代码
java·视频流
邪恶的贝利亚1 小时前
定时器设计
java·linux·前端
工业互联网专业1 小时前
基于springboot+vue的机场乘客服务系统
java·vue.js·spring boot·毕业设计·源码·课程设计·机场乘客服务系统
饕餮争锋1 小时前
WebMvcConfigurer介绍-笔记
java·笔记·servlet