哈喽各位小伙伴,欢迎继续收听Java入门播客!上一期我们完整学习了接口的语法、规则以及和抽象类的区别。今天我们来学习内部类,也就是定义在类里面的类。内部类是Java中比较灵活的语法结构,一共分为四大类型,不同类型用法、创建方式、访问规则都不一样,也是日常编码和面试的常见知识点,我们一起来逐个学习。 首先先来了解内部类的基础概念。顾名思义,内部类就是定义在另一个类内部的类,外层的类我们称之为外部类。 有几个通用特点大家先记好:第一,内部类编译完成后,同样会生成独立的class文件,文件命名格式为外部类名$内部类名.class;第二,内部类可以直接访问外部类的私有成员,这个特性既方便代码编写,又不会破坏外部类本身的封装性。 按照定义位置和修饰符区分,内部类总共分为四种:成员内部类、静态内部类、局部内部类、匿名内部类,接下来我们依次讲解。 第一种:成员内部类,大家可以把它类比成类中的实例变量。它的定义位置在外部类内部、所有方法之外。这里有一个核心规则:成员内部类不能独立创建对象,必须先创建外部类对象,再依托外部类实例来创建内部类对象。 书写格式分两步:先 外部类 外部对象 = new 外部类() ,再通过 外部对象.new 内部类() 创建内部类实例。如果想要在内部类中明确访问外部类的成员,可以使用 外部类名.this 的写法,搭配属性名或方法名,精准调用外部类的内容。最后注意一条限制:成员内部类当中,不允许定义静态成员,也就是不能写静态属性和静态方法。 第二种:静态内部类,对应类比类中的静态变量,它是在成员内部类的基础上,增加了 static 修饰符。 静态内部类的使用规则和成员内部类有明显区别。首先,它内部既可以定义实例变量,也可以定义静态变量,使用不受限。其次,创建静态内部类对象不需要依赖外部类对象,直接通过 外部类名.内部类名 就能new对象,写法更加简洁。 如果要访问静态内部类里的静态成员,直接使用 外部类名.静态内部类名.成员名 即可。还有一条访问权限规则:静态内部类只能访问外部类的静态属性和静态方法,无法直接使用外部类的普通实例成员,这一点和静态方法的访问规则保持一致。 第三种:局部内部类,可以类比成方法里的局部变量。它的定义位置很特殊,必须写在方法内部。对应的,它的对象也只能在当前方法内部、类定义完成之后进行创建,出了这个方法就无法使用。 重点来说访问规则:局部内部类中的方法,可以访问所在方法里的局部变量。在JDK8之前,要求被访问的局部变量必须手动加上 final ;而从JDK8开始,编译器提供了语法糖,只要局部变量被局部内部类调用,会默认隐式添加final修饰,我们不用手动书写,大家了解这个版本差异即可。 第四种:匿名内部类,它是使用频率最高的一种,同时也是特殊的局部内部类。 首先明确核心规则:匿名内部类在定义时,必须继承一个父类,或者实现一个接口。它最大的特点是,类的定义和对象创建同步完成,并且基于一段匿名代码,只能创建唯一一个对象,没有类名,这也是“匿名”的由来。 我们来看标准语法:如果是实现接口,写法就是 接口名 引用 = new 接口名(){ 重写接口中的所有抽象方法 }; ;如果是继承普通类,写法也基本一致,在大括号中重写父类需要覆盖的方法就可以。 简单评价它的优缺点:优点是代码精简,省去了单独定义实现类、子类的步骤,让业务逻辑衔接更连贯;缺点也很明显,因为没有类名,代码可读性会下降,所以不适合用来编写体量较大、逻辑复杂的代码。 (语气放缓,总结梳理) 以上就是四种内部类的全部知识点了。我们简单做个区分复盘:成员内部类、静态内部类定义在类中方法外,前者依赖外部对象、不能定义静态成员,后者依托外部类名即可使用,仅能访问外部静态成员;局部内部类写在方法内部,受局部变量作用域和final规则约束;匿名内部类是简化写法,依附接口或父类,定义和创建对象一步完成,适合临时使用。 内部类语法细节较多,建议大家结合案例动手编写代码,区分不同类型的创建方式和访问限制。掌握内部类之后,我们对Java类的嵌套结构就有了完整认知。 本期播客到这里就结束了,我们下期再见!
Java学习播客第十一期:详解四类内部类,掌握嵌套类用法