> 文档中心 > 【JavaSE】程序员的分水岭?四种内部类专题

【JavaSE】程序员的分水岭?四种内部类专题


💁 个人主页:Nezuko627的博客主页 欢迎来访~~~
❤️ 支持我:👍 点赞 🌷 收藏 🤘关注
🎏 格言:立志做一个有思想的程序员 🌟
📫 作者介绍:本人本科软件工程在读,博客及技术将主要涉及JavaSE、JavaEE、MySQL、SpringBoot、算法等。专栏内容长期更新,如有错误,欢迎评论区或者私信指正!谢谢大家的支持~~~

本篇学习目标:

  • ⭐️ 熟悉内部类的划分及分类;
  • ⭐️ 掌握四种内部类的基本使用方式;
  • ⭐️ 理解四种内部类的应用场景;
  • ⭐️ 重点掌握匿名内部类的使用与本质。

本文来自专栏:JavaSE系列专题知识及项目 欢迎点击支持订阅专栏 ❤️
在这里插入图片描述

文章目录

  • 1 内部类及其分类概述
  • 2 局部内部类
  • 3 匿名内部类(重点)
    • 3.1 匿名内部类的使用与本质
    • 3.2 匿名内部类的使用场景
  • 4 成员内部类
  • 5 静态内部类
  • 写在最后

1 内部类及其分类概述

🚗 基本介绍:
一个类的内部又完整的嵌套了另一个类的结构。 被嵌套的类称为内部类,嵌套其他类的类称为外部类。内部类的最大特点是 可以直接访问其私有属性,并且体现类与类的包含关系。
Tips: 类的五大成员: 属性、方法、构造器、代码块、内部类。
🅰️ 基本语法:

class Outer{  // 外部类class Inner{  // 内部类}}

🐑 内部类的分类:
在这里插入图片描述


2 局部内部类

🆔 说明: 局部内部类是定义在外部类的局部位置,比如定义在方法中,且有类名。
👧 局部内部类的特性:

1️⃣ 局部内部类可以直接访问外部类的所有成员,包含私有的;
在这里插入图片描述

2️⃣ 不能添加访问修饰符, 因为局部内部类的地位实际是一个局部变量。但是可以用 final 修饰;
在这里插入图片描述

3️⃣ 作用域:定义的方法或者代码块中;

4️⃣ 外部类在方法中,可以通过创建内部类的对象,访问内部类的成员。
在这里插入图片描述

5️⃣ 外部其他类,不能访问局部内部类;
在这里插入图片描述

6️⃣ 如果外部类和内部类的成员重名,则遵循就近原则。如果想访问外部类成员,则可以通过 外部类名.this.成员名 的方式访问;
🍌 示例代码:

public class LocalInnerClass {  // 外部其他类    public static void main(String[] args) { Outer outer = new Outer(); outer.method1();    }}class Outer{  // 外部类    private int attribute = 20;  // 外部类私有属性    public void method1(){  // 成员方法 class Inner{  // 内部类     private int attribute = 100;  // 内部部类私有属性     // 可以直接访问外部类所有成员,包括私有的     public void m1(){  System.out.println(attribute);  // 就近原则 100  System.out.println(Outer.this.attribute);  // 20     } } new Inner().m1();  // 使用内部类的m1    }}

🍎 实现结果:

100
20

🐍 解释: 外部类名.this.成员名 本质就是外部类的对象,示例中 Outer.this 指代外部其他类创建的对象 outer。


3 匿名内部类(重点)

3.1 匿名内部类的使用与本质

🐭 与局部内部类相类似的是,匿名内部类也是定义在外部类的局部位置,但是其 没有类名。 其本质还是一个内部类, 同时也是一个对象。

🅰️ 匿名内部类的基本语法:

new 类名或接口名(参数列表){类体};

❓ 看到这,你可能就会问 ,接口不是不能实例化吗,为啥匿名内部类可以直接写接口名? 实际上,当你写接口名的时候,需要同时实现接口的所有抽象方法, 示例代码如下:

public class AnonymousInnerClass {    public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.method();    }}// 接口interface Animals{    void say();}// 外部类class OuterClass{    void method(){ Animals dog = new Animals() {     @Override     public void say() {  System.out.println("汪汪汪~~~");     } }; dog.say(); System.out.println("匿名内部类名称:" + dog.getClass());    }}

🍎 其实匿名内部类是有类名的,只不过是被系统底层隐藏起来了,类名为 外部类名称$1上述代码中 jdk 底层在创建匿名内部类 OuterClass$1 立马创建了其实例,返回给了 dog , 实现结果如下:

汪汪汪~~~
匿名内部类名称:class outerinner.OuterClass$1

为什么要使用匿名内部类?

为了简化开发,有些类我们不需要反复使用,只需要使用一次,就会使用匿名内部类。匿名内部类只能使用一次,但匿名内部类的引用却可以多次使用。在刚刚的示例中,dog对象可以反复使用,但是 new 的匿名内部类只创建了一次,当 dog 不再使用的时候,由于匿名内部类缺少类名,我们将没有其他途径访问到它。

示例中我们也可以不使用 dog 来引用匿名内部类,而是直接使用一次!修改后的参考代码如下:

public class AnonymousInnerClass {    public static void main(String[] args) { new OuterClass().method();    }}// 接口interface Animals{    void say();}// 外部类class OuterClass{    void method(){ new Animals() {     @Override     public void say() {  System.out.println("汪汪汪~~~");     } }.say();    }}

3.2 匿名内部类的使用场景

将匿名内部类 当作实参直接传递
🍌 示例代码:

public class AnonymousInnerClass {    public static void main(String[] args) { show(new Animals() {     @Override     public void say() {  System.out.println("传进来啦!");     } });    }    public static void show(Animals animal){ animal.say();    }}// 接口interface Animals{    void say();}

🍎 实现结果:

传进来啦!


4 成员内部类

✋ 成员内部类是定义在外部类的成员位置,且没有 static 修饰的类。
👧 成员内部类的特性:
1️⃣ 成员内部类 可以直接访问外部类的所有成员, 包括私有的;
在这里插入图片描述
2️⃣ 由于其本质是成员,所以 对于访问修饰符没有限制;

3️⃣ 外部类可以通过创建对象的方式访问内部类的成员,且不受修饰符的影响;
在这里插入图片描述
4️⃣ 外部其他类也可以通过创建对象的方式来访问内部类的成员,但是,受到访问修饰符的影响,内部类的私有成员不能直接被访问;
🍑 外部其他类创建访问内部类对象的形式:

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

🍌 示例:
在这里插入图片描述
👧 也可以 在外部类中提供一个获取内部类对象的方法,同样可以获取内部类对象:

在这里插入图片描述
5️⃣ 如果外部类和内部类成员重名时,内部类被访问的话,遵循就近原则;如果想访问外部类的成员,可以使用 外部类名.this.成员 的方式;

🍑 下面的代码中,say() 方法访问的是内部类的 name,即 Dog:

class Animal{  // 外部类    private String name = "Animal";    class Dog{  // 内部类 private String name = "Dog"; public void say(){     System.out.println("My name is " + name); }    }}

5 静态内部类

✈️ 与成员内部类的区别在于,静态内部类有 static 修饰,具有类变量的特性。
👧 静态内部类的特性:
1️⃣ 可以直接访问外部类的所有静态成员,但不能访问外部类的非静态成员;

2️⃣ 外部类可以通过创建对象的方式访问静态内部类, 该点与前面其他内部类的叙述类似,不再赘述;

3️⃣ 外部其他类访问静态内部类的方式:

⭐️方式1(在不考虑访问修饰符的前提下,静态内部类是可以通过类名直接访问的):
外部类名.内部类名 对象名 = new 外部类名.内部类名();

⭐️方式2:外部类 提供获取内部类的非静态方法:
在这里插入图片描述
⭐️方式3:外部类 提供获取内部类的静态方法:
在这里插入图片描述

4️⃣ 如果外部类与静态内部类的成员重名时,静态内部类访问该成员,同样遵守就近原则;如果想要访问外部类的成员,则使用 外部类名.成员


写在最后

🌟以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞 + 关注,非常感谢 ❤️ ❤️ ❤️ !
如果有问题,欢迎私信或者评论区!
在这里插入图片描述

共勉:“你间歇性的努力和蒙混过日子,都是对之前努力的清零。”
在这里插入图片描述