Java 内部类的四种实现方式


前言

今天的话我将为大家介绍Java的四种内部类,他们分别是普通内部类,静态内部类,局部内部类,匿名内部类。


提示:以下是本篇文章正文内容,下面案例可供参考

一、内部类是什么?

  • 当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类(Inner),而这个内部类所在的类叫做外部类(Outer)。

  • 当一个类存在的价值仅仅是为某一个类单独服务时,那么就可以将这个类定义为所服务类中的内部类,这样可以隐藏该类的实现细节并且可以方便的访问外部类的私有成员而不再需要提供公有的get和set方法。

二、内部类的分类

2.1 普通内部类

普通内部类-直接将一个类的定义放在另外一个类的类体中。(对象层级)

这种内部类的写法其实和外部类也基本是一致的。

普通内部类的特点:

  • 普通内部类可以使用的关键字为:public,private,protected,final,abstract
  • 普通内部类和普通类一样可以定义成员变量、成员方法以及构造方法等。
  • 普通内部类需要使用外部类对象来创建对象。
  • 如果内部类访问外部类中与本类内部同名的成员变量或方法时,需要使用this关键字。
    语法格式:
访问修饰符 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: 3innerClass.show();// Inner class: 33//Inner class: 33//Inner class: 33//Outer class: 3}
}

运行结果:

2.2 静态内部类

静态内部类-使用static关键字修饰的内部类,隶属于类层级。(类层级)
语法格式:

访问修饰符 class 外部类的类名{访问修饰符 static class 内部类的类名{内部类的类体;}
}

静态内部类的特点:

  • 静态内部类不能直接访问外部类的非静态成员。
  • 静态内部类可以直接创建对象。
  • 如果静态内部类访问外部类中与本类内同名的成员变量或方法时,需要使用类名.的方式访问。

静态内部类调用外部类中的成员变量:

  • 第一种方式可以将静态外部类的类型写为static,然后在静态内部列使用 类名. 的形式引用
  • 第二种方式可以在静态内部类中 new 对象,然后进行引用

案例:

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: 5innerClass.show();// Inner class: 55//Inner class: 55//Inner class: 55//Outer class: 静态成员变量 5//Outer class: 非静态成员变量 555}
}

运行结果:

2.3 局部内部类

局部内部类-直接将一个类的定义放在方法体的内部时。(方法块层级)
语法格式:

访问修饰符 class 外部类的类名{访问修饰符 返回值类型 成员方法名(形参列表){class 内部类的类名{内部类的类体;}}
}

局部内部类的特点:

  • 局部内部类只能在该方法的内部可以使用。
  • 局部内部类可以在方法体内部直接创建对象。
  • 局部内部类不能使用访问控制符和static关键字修饰符
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。

案例:

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}
}

运行结果:

2.4 匿名内部类(最常用)

匿名内部类-就是指没有名字的内部类。
语法格式:

  • 常规写法:
接口/父类类型 引用变量名= new 接口/父类类型() { 方法的重写};
  • lambda写法(Java8之后的特性)
(参数列表) -> (方法体)

案例:

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() {@Overridepublic void show() {System.out.println("这是 匿名内部类 常规写法");}};anonymousInterface.show(); // 这是 匿名内部类 常规写法// 第二种:匿名内部类,lambda写法,更加简单(Java8)AnonymousInterface anonymousInterface1 = () -> System.out.println("这是 匿名内部类 lambda写法");anonymousInterface1.show(); // 这是 匿名内部类 lambda写法}
}

三,总结

以上就是Java的四种内部类的实现方式,相对来说,匿名内部类会更常用一些,而且匿名内部类如果使用lambda写法会更加的简洁。

好了,本期内容就到这里,谢谢大家。


Java 内部类的四种实现方式相关推荐

  1. Java内部类的四种分类以及作用

    本文转载自:Java内部类的四种分类以及作用 一.内部类内容解析 1. 内部类的区分 内部类分别有成员内部类.局部内部类.匿名内部类.静态内部类,接下来将分别介绍. 2. 成员内部类 就是位于外部类成 ...

  2. Java:简述Java多线程的四种实现方式

    关联文章:<Java:简述Java中的多线程编程> Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来 ...

  3. Java对象的四种引用方式

    本文会按照以下思路进行: (1)Java的四种对象引用的基本概念 (2)四种对象引用的差异对比 (3)对象可及性的判断以及与垃圾回收机制的关系 (4)引用队列ReferenceQueue的介绍 (5) ...

  4. Java中的四种引用方式的区别

    强引用.软引用.弱引用.虚引用的概念 ps:我更新了.....我真的更新了.....因为博客园不支持MarkDown,而且取了一个很low的用户名,所以不用了..... 强引用(StrongRefer ...

  5. 面试官:说说Java对象的四种引用方式

    我们知道在Java中除了基础的数据类型以外,其它的都为引用类型. 而Java根据其生命周期的长短将引用类型又分为强引用.软引用.弱引用.幻象引用 . 正常情况下我们平时基本上我们只用到强引用类型,而其 ...

  6. JAVA四种引用方式

    JAVA四种引用方式: java.lang.ref: 强引用(直接变量赋值) 软引用(SoftReference): 只有在要发生OOM错误之前才会回收掉老的软引用对象,应用场景主要防止内存溢出.(缓 ...

  7. Java的四种引用方式

    Java的四种引用方式 java内存管理分为内存分配和内存回收,都不需要程序员负责,垃圾回收的机制主要是看对象是否有引用指向该对象. java对象的引用包括   强引用,软引用,弱引用,虚引用 Jav ...

  8. Java线程池的四种创建方式

    Java线程池的四种创建方式 Java使用Thread类来表示线程,所有的线程都是Thread类或者是他的子类.Java有四种方式来创建线程. (1)继承Thread类创建线程 (2)实现Runnab ...

  9. java的rest教程_[Java教程]SpringMVC的REST风格的四种请求方式

    [Java教程]SpringMVC的REST风格的四种请求方式 0 2017-08-28 22:00:25 一. 在HTTP 协议里面,四个表示操作方式的动词:GET.POST.PUT.DELETE. ...

最新文章

  1. desk next the to_仁爱版七年级下册英语句型转换题型专练
  2. C语言main()函数详解
  3. C++中查看数据类型的方法
  4. 【转】Hibernate数据过滤
  5. Container ViewController自定义转场控制器。
  6. 更改管理员密码以后网站不能启动
  7. centos dns服务器_用 OpenStack Designate 构建一个 DNS 即服务(DNSaaS) | Linux 中国
  8. 功能接口 java8_Java 8功能接口
  9. unity 创建NGUI字体
  10. Reverse Integer(C++)
  11. html动态背景gif图片,gif动态背景
  12. access用姓名字段统计人数_access题库61-66(1)
  13. 最近智商拙计,做做题补一下
  14. QT框架下的OpenGL使用---实战篇---鼠标选取点对象
  15. 用户划分——RMF方法
  16. 【Simapro软件教程】参数进行灵敏度分析
  17. 回归预测 | MATLAB实现SSA-BP多输入单输出回归预测
  18. 不修条地铁,都不好意思叫自己大城市(附地铁发展图)
  19. java linux mdb,在Linux下实现对Microsoft Access Database(.mdb)查询访问
  20. 传感网应用开发知识点总结

热门文章

  1. 家里有甲醛怎么去除 怎么判断家里有甲醛
  2. MoreLikeThis 相似检索
  3. 关于iOS禁止输入表情符号
  4. 键盘录入两个整数,求他们的最大公约数
  5. 设计模式 行为型模式 实例 -- 备忘录模式实例:游戏备忘录
  6. nginx配置http和https共存
  7. android xutils框架缓存图片,xUtils框架的使用
  8. 使用Mathtype的“插入下一章”导致整个自动生成的目录出现难看的章节号
  9. 日本的mmx任务将捕获火星及其卫星的8k图像
  10. 如何用键盘选择要复制粘贴的文字