今天的话我将为大家介绍Java的四种内部类,他们分别是普通内部类,静态内部类,局部内部类,匿名内部类。
提示:以下是本篇文章正文内容,下面案例可供参考
当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类(Inner),而这个内部类所在的类叫做外部类(Outer)。
当一个类存在的价值仅仅是为某一个类单独服务时,那么就可以将这个类定义为所服务类中的内部类,这样可以隐藏该类的实现细节并且可以方便的访问外部类的私有成员而不再需要提供公有的get和set方法。
普通内部类-直接将一个类的定义放在另外一个类的类体中。(对象层级)
这种内部类的写法其实和外部类也基本是一致的。
普通内部类的特点:
访问修饰符 class 外部类的类名{
访问修饰符 class 内部类的类名{
内部类的类体;
}
}
案例:
package com.lagou.task03.generalClass;
/**
* @author 云梦归遥
* @date 2021/11/22 16:18
* @description
*/
public class GeneralClass {
private int cnt;
public GeneralClass() {
}
public GeneralClass(int cnt) {
setCnt(cnt);
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public void show() {
System.out.println("Outer class: " + getCnt());
}
// 创建第一种内部类:普通内部类
public class InnerClass {
private int cnt;
public InnerClass() {
}
public InnerClass(int cnt) {
setCnt(cnt);
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public void show() {
// 当内部类和外部类成员变量名相同时
// 上面三种都是获取 内部类 成员变量的方法
// 最后一种是获取 外部类 成员变量的方法
System.out.println("Inner class: " + getCnt());
System.out.println("Inner class: " + this.getCnt());
System.out.println("Inner class: " + InnerClass.this.getCnt());
System.out.println("Outer class: " + GeneralClass.this.getCnt()); // 使用 this 关键字
}
}
}
对应的测试类:
package com.lagou.task03.generalClass;
/**
* @author 云梦归遥
* @date 2021/11/22 16:33
* @description
*/
public class GeneralClassTest {
public static void main(String[] args) {
GeneralClass generalClass = new GeneralClass(3);
// 使用外部类对象 实例化 内部类对象
GeneralClass.InnerClass innerClass = generalClass.new InnerClass(33);
generalClass.show(); // Outer class: 3
innerClass.show();
// Inner class: 33
//Inner class: 33
//Inner class: 33
//Outer class: 3
}
}
静态内部类-使用static关键字修饰的内部类,隶属于类层级。(类层级)
语法格式:
访问修饰符 class 外部类的类名{
访问修饰符 static class 内部类的类名{
内部类的类体;
}
}
静态内部类的特点:
静态内部类调用外部类中的成员变量:
案例:
package com.lagou.task03.staticClass;
/**
* @author 云梦归遥
* @date 2021/11/22 16:41
* @description
*/
public class StaticClass {
private static int cnt;
private int cnt2;
public StaticClass() {
}
public StaticClass(int cnt) {
setCnt(cnt);
}
public static int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public int getCnt2() {
return cnt2;
}
public void setCnt2(int cnt2) {
this.cnt2 = cnt2;
}
public void show() {
System.out.println("Outer class: " + getCnt());
}
// 创建第二种内部类:静态内部类
public static class InnerClass {
private int cnt;
public InnerClass() {
}
public InnerClass(int cnt) {
setCnt(cnt);
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public void show() {
// 当内部类和外部类成员变量名相同时
// 上面三种都是获取 内部类 成员变量的方法
System.out.println("Inner class: " + getCnt());
System.out.println("Inner class: " + this.getCnt());
System.out.println("Inner class: " + InnerClass.this.getCnt());
// 最后一种是获取 外部类 成员变量的方法,
// 1.静态内部类中调用外部的变量必须也是静态的才行
System.out.println("Outer class: 静态成员变量 " + StaticClass.getCnt());
// 2.在静态内部类中 new 外部类的对象,然后进行引用
StaticClass staticClass = new StaticClass();
staticClass.setCnt2(555);
System.out.println("Outer class: 非静态成员变量 " + staticClass.getCnt2());
}
}
}
对应的测试代码:
package com.lagou.task03.staticClass;
/**
* @author 云梦归遥
* @date 2021/11/22 16:49
* @description
*/
public class StaticClassTest {
public static void main(String[] args) {
StaticClass staticClass = new StaticClass(5);
StaticClass.InnerClass innerClass = new StaticClass.InnerClass(55);
staticClass.show(); // Outer class: 5
innerClass.show();
// Inner class: 55
//Inner class: 55
//Inner class: 55
//Outer class: 静态成员变量 5
//Outer class: 非静态成员变量 555
}
}
局部内部类-直接将一个类的定义放在方法体的内部时。(方法块层级)
语法格式:
访问修饰符 class 外部类的类名{
访问修饰符 返回值类型 成员方法名(形参列表){
class 内部类的类名{
内部类的类体;
}
}
}
局部内部类的特点:
案例:
package com.lagou.task03.areaClass;
/**
* @author 云梦归遥
* @date 2021/11/22 16:58
* @description
*/
public class AreaClass {
private int cnt;
public AreaClass(int cnt) {
setCnt(cnt);
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public void show() {
System.out.println("Outer class: " + getCnt());
// 如果 内部类要使用 局部变量,为了保证数据的一致性,将局部变量设置为 final
// 添加的原因:局部变量比局部内部类的作用范围更大,当局部内部类在使用时,会在底层从局部变量复制一份到局部内部类
// 如果不使用final,当在局部内部类的外部修改这个变量的值以后,就会造成数据的不一致性
final int snt = 6666;
// 局部内部类不需要,也不能使用 访问控制符 和 static 进行修饰
class InnerClass {
private int cnt;
public InnerClass() {
}
public InnerClass(int cnt) {
this.cnt = cnt;
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public void show() {
System.out.println("Inner class: " + getCnt());
System.out.println("snt : " + snt);
}
}
InnerClass innerClass = new InnerClass(666);
innerClass.show();
}
}
对应的测试类:
package com.lagou.task03.areaClass;
/**
* @author 云梦归遥
* @date 2021/11/22 17:06
* @description
*/
public class AreaClassTest {
public static void main(String[] args) {
AreaClass areaClass = new AreaClass(66);
areaClass.show();
// Outer class: 66
//Inner class: 666
//snt : 6666
}
}
匿名内部类-就是指没有名字的内部类。
语法格式:
接口/父类类型 引用变量名= new 接口/父类类型() { 方法的重写};
(参数列表) -> (方法体)
案例:
package com.lagou.task03.anonymousClass;
/**
* @author 云梦归遥
* @date 2021/11/22 17:39
* @description
*/
public interface AnonymousInterface {
public void show();
}
对应的测试类:
package com.lagou.task03.anonymousClass;
/**
* @author 云梦归遥
* @date 2021/11/22 17:42
* @description
*/
public class AnonymousInterfaceTest {
public static void main(String[] args) {
// 第一种:匿名内部类,常规写法
AnonymousInterface anonymousInterface = new AnonymousInterface() {
@Override
public void show() {
System.out.println("这是 匿名内部类 常规写法");
}
};
anonymousInterface.show(); // 这是 匿名内部类 常规写法
// 第二种:匿名内部类,lambda写法,更加简单(Java8)
AnonymousInterface anonymousInterface1 = () -> System.out.println("这是 匿名内部类 lambda写法");
anonymousInterface1.show(); // 这是 匿名内部类 lambda写法
}
}
以上就是Java的四种内部类的实现方式,相对来说,匿名内部类会更常用一些,而且匿名内部类如果使用lambda写法会更加的简洁。
好了,本期内容就到这里,谢谢大家。