Java基础_内部类

文章目录

    • 1.基本介绍
        • 1.定义:
        • 2.基本语法:
        • 3.内部类的分类
    • 2.局部内部类
        • 1.快速入门
        • 2.局部内部类的使用
    • 3.匿名内部类
        • 1.匿名内部类实现接口
        • 2.匿名内部类继承抽象类
        • 3.匿名内部类细节
        • 4.匿名内部类最佳实践
          • 1.匿名内部类作为实参传入函数
          • 2.匿名内部类课堂练习
    • 4.成员内部类
        • 成员内部类的使用
    • 5.静态内部类
        • 静态内部类的使用

1.基本介绍

1.定义:

一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他类的类被称为外部类。

2.基本语法:

image-20231211202901842

3.内部类的分类
  1. 定义在外部局部位置上(比如方法内):
    1. 局部内部类(有类名)
    2. 匿名内部类(没有类名)
  2. 定义在外部类的成员位置上
    1. 成员内部类(没用static修饰)
    2. 静态内部类(使用static修饰)

2.局部内部类

1.快速入门
package innerclass;public class LocalInnerClass {public static void main(String[] args) {new Outer02().m1();}
}class Outer02 { //外部类private int n1 = 100;private void m2() { //私有方法System.out.println("这是外部类的私有方法");}public void m1() {class Inner02 { //局部内部类,是放在代码块或者方法中(本质仍然是一个类)public void f1() {System.out.println("外部类的私有属性:" + n1); //局部内部类可以直接访问外部类的所有私有成员}}class Inner03 extends Inner02 { //局部内部类可以被继承public void f2() {super.f1(); //可以访问父类的方法m2();//还可以访问外部类的私有方法}}new Inner03().f2(); //在方法中创建局部内部类的对象然后调用方法}}
2.局部内部类的使用
  1. 局部内部类既是一个局部变量又是一个类

  2. 局部内部类可以访问外部类的所有成员,包括私有的

  3. 不能添加访问修饰符,因为他的地位是一个局部变量,但是可以使用final修饰

  4. 作用域:仅仅在定义他的方法或者代码块中

  5. 外部类访问局部内部类的方式,在方法或者代码块中声明局部内部类的对象然后调用

  6. 外部其他类不能访问局部内部类,因为局部内部类地位是一个局部变量

  7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用

    外部类名.this.成员
    

    外部类名.this的意思是外部类的一个对象,就相当于普通类中的this,谁调用的这个方法,则这个对象就是谁

  8. 代码实例

    package innerclass;public class LocalInnerClass {public static void main(String[] args) {new Outer02().m1();}
    }class Outer02 { //外部类private int n1 = 100;public void m1() {class Inner02 { //局部内部类,是放在代码块或者方法中(本质仍然是一个类)int n1 = 200; //与外部类中的属性重名,默认遵循就近原则public void f1() {System.out.println("局部内部类中的n1 = " + n1); //根据就近原则,访问了局部内部类中的n1System.out.println("外部类中的n1 = " + Outer02.this.n1);}}new Inner02().f1();}
    }
    

3.匿名内部类

1.匿名内部类实现接口
  1. 需求:想使用一个接口,并创建对象,但是只使用一次

  2. 传统方式:写一个类,实现接口,并创建对象

  3. 可以使用匿名内部类来简化开发

  4. jdk底层:创建了一个匿名内部类,实现了接口,然后返回一个这个匿名内部类的对象

  5. 代码实例

    package innerclass;public class AnonymousInnerClass {public static void main(String[] args) {new Out().method();}
    }
    interface IA {void cry();
    }
    class Out { //外部类public void method() {IA tiger = new IA() { //编译类型是IA , 运行类型是匿名内部类Out$1@Overridepublic void cry() {System.out.println("老虎在哭");}}; //匿名内部类,底层进行了,写一个匿名内部类,实现了接口IA,然后返回了一个对象tiger.cry();System.out.println("匿名内部类的名字:" + tiger.getClass());}
    }
    

    image-20231211215756320

2.匿名内部类继承抽象类
  1. 匿名内部类可以继承普通类或者抽象类

  2. jdk底层:创建一个匿名内部类,继承了抽象类,重写抽象类的抽象方法,返回一个匿名内部类的对象,如果有构造器相当于调用了父类的构造器

  3. 代码实例

    package innerclass;public class AnonymousInnerClass {public static void main(String[] args) {new Out().method();}
    }
    abstract class Father1 {public Father1(String name) {}public abstract void cry(); //抽象方法
    }
    class Out { //外部类public void method() {Father1 father = new Father1("父亲") { //匿名内部类整个过程相当于,1.创建一个匿名内部类 2.继承了Father类 3.返回一个匿名内部类的对象//这个匿名内部类继承了抽象类则需要重写抽象方法@Overridepublic void cry() {System.out.println("匿名内部类重写了父类的抽象方法");}};father.cry();}
    }
    

image-20231212195939957

3.匿名内部类细节
  1. 匿名内部类是以一个类似于类的形式展示,但是其实他是这个类返回的一个对象,所以可以直接使用这个匿名内部类对象来访问里面的成员image-20231212203652491

  2. 匿名内部类可以直接访问外部类的所有成员,包括私有的

  3. 不能给匿名内部类直接添加访问修饰符,因为匿名内部类本身也是一个局部变量

  4. 匿名内部类的作用域:仅仅在定义它的方法或代码块中

  5. 匿名内部类访问外部类的成员的方式是直接访问

  6. 如果内部类的属性跟外部类的属性冲突,则可以使用类名.this.属性名的方式访问外部类的属性

  7. 其他外部类不能访问匿名内部类,因为匿名内部类只是一个局部变量

  8. 代码实例

    package innerclass;public class AnonymousInnerClassDetail {public static void main(String[] args) {new Outer05().f1();}
    }
    class Person {public void hi(String name) {System.out.println("你好:" + name);}
    }
    class Outer05 {private int n1 = 99;public void f1() {new Person() { //匿名内部类继承了Person类@Overridepublic void hi(String name) { //重写了hi方法super.hi(name);}}.hi("小明");//这相当于匿名内部类的一个对象可以直接调用方法new Person() {int n1 = 100; //这里的属性跟外部类的属性重名了public void printn1() {System.out.println("外部类的n1:" + Outer05.this.n1); //使用外部类名.this.属性名来访问与内部类重名的外部属性System.out.println("内部类的n1:" + n1);}}.printn1();}
    }

    image-20231212205039151

4.匿名内部类最佳实践
1.匿名内部类作为实参传入函数
package innerclass;public class InnerclassExercise01 {public static void main(String[] args) {f1(new IL() {@Overridepublic void show() {System.out.println("我实现了接口的IL方法");}}); //使用匿名内部类直接作为实参传入函数}public static void f1(IL li) {li.show();}
}
interface IL {void show();
}
2.匿名内部类课堂练习

image-20231212212321281

  1. 代码

    package innerclass;public class InnerclassExercise02 {public static void main(String[] args) {new CellPhone().alarmclock(new Bell() {@Overridepublic void ring() {System.out.println("懒猪起床了");}});new CellPhone().alarmclock(new Bell() {@Overridepublic void ring() {System.out.println("小伙伴上课了");}});}
    }
    interface Bell {void ring();
    }
    class CellPhone {public void alarmclock(Bell bell) {bell.ring();}
    }
    
  2. 结果image-20231212212603366

4.成员内部类

成员内部类的使用
  1. 说明:成员内部类是定义在外部类的成员位置,并且没有static修饰

  2. 可以直接访问外部类的所有成员,包括私有的

  3. 可以添加任何访问修饰符,因为他的定位就是一个成员

  4. 作用域:和外部类的其他成员一样

  5. 成员内部类访问外部类的成员可以直接访问,当成员内部类的成员跟外部类的成员重名的时候,使用外部类名.this.成员名来访问

  6. 外部类访问成员内部类,创建对象访问

  7. 代码实例

    package innerclass;public class MemberInnerClass01 {public static void main(String[] args) {new Outer01().f1();Outer01 outer01 = new Outer01();}
    }
    class Outer01 { //外部类private int n1 = 10;public String name = "张三";public class Innter01 { //成员内部类public String name = "李四"; //成员内部类的属性跟外部类重名public void say() {System.out.println("Outer01的n1:" + n1 + " Outer01的name:" + Outer01.this.name); //成员内部类可以访问外部类的所有成员,当重名的时候需要使用外部类名.this.属性名来访问}}public void f1() {//使用成员内部类Innter01 innter01 = new Innter01(); //外部类访问成员内部类,创建对象访问innter01.say();}
    }

    image-20231213194515782

  8. 外部其他类访问成员内部类有两种方式

    1. 通过外部类的实例来访问并创建一个成员内部类的实例
    2. 在外部类中暴露一个方法返回成员内部类的实例
    package innerclass;public class MemberInnerClass02 {public static void main(String[] args) {//外部其他类访问成员内部类的第一种方式,使用外部类的实例来访问内部类并创建对象Outer06.Innter innter = new Outer06().new Innter();innter.method();//第二种方式,在外部类中写一个方法直接返回成员内部类的对象Outer06.Innter innter1 = new Outer06().getInnter();innter1.method();}
    }
    class Outer06 { //外部类public class Innter { //成员内部类public void method() {System.out.println("我是成员内部类");}}public Innter getInnter() { //向外暴露一个方法来获得成员内部类的对象return new Innter();}
    }

5.静态内部类

静态内部类的使用
  1. 说明:静态内部类是有static的在成员位置的内部类

  2. 可以直接访问外部类的所有静态成员,包括私有的,但是不能直接访问非静态成员

  3. 可以添加任何访问修饰符,因为他的地位是一个成员

  4. 作用域:同其他的成员

  5. 静态内部类访问外部类的静态成员可以直接访问,如果重名,则使用外部类名.成员名来访问(不加this的原因静态内部类只能访问静态成员,所以就没有加this的必要)

  6. 外部类访问静态内部类 创建对象再访问

  7. 外部其他类访问静态内部类有三种方式

    package innerclass;public class StaticInnerClass01 {public static void main(String[] args) {//外部其他类访问静态内部类的第一种方式,创建对象访问Outer07.Inner02 inner02 = new Outer07.Inner02(); //因为他是静态的所以是是属于类的可以直接用类名访问inner02.say();//外部其他类访问静态内部类的第二种方式,在外部类中暴露一个普通方法返回静态内部类的实例Outer07.Inner02 inner021 = new Outer07().getInner02();inner021.say();//外部其他类访问静态内部类的第三种方式,在外部类中暴露一个静态方法返回静态内部类的实例Outer07.Inner02 inner022 = Outer07.getInner02_();inner022.say();}
    }
    class Outer07 { //外部类public static class Inner02 {public void say() {System.out.println("我是静态内部类");}}public Inner02 getInner02() { //普通方法返回静态内部类实例return new Inner02();}public static Inner02 getInner02_() { //静态方法返回静态内部类实例return new Inner02();}
    }
  8. 练习image-20231213205751598image-20231213205815184

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/537591.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法详解——图的深度优先遍历和广度优先遍历

目录 一、图结构二、深度优先遍历2.1 图的遍历2.2 深度优先遍历过程2.3 深度优先遍历核心思想2.4 深度优先遍历实现 三、广度优先遍历3.1 广度优先遍历过程3.2 广度优先遍历核心思想3.3 广度优先遍历实现 参考文献 一、图结构 图结构指的是如下图所示的由节点和边组成的数据。 …

最新CLion + STM32 + CubeMX 开发环境搭建

网上有不少相关教程,但都是基于老版本Clion,新版有一些改变,但整体是简单了。 PS:本教程基于CLion 2023.3.4 安装所需工具参考:Clion搭建stm32开发环境(STM32F103C8T6),有这一篇就够…

【论文速读】| MOCK:上下文依赖引导的内核模糊测试

本次分享论文为:MOCK: Optimizing Kernel Fuzzing Mutation with Context-aware Dependency 基本信息 原文作者:Jiacheng Xu,Xuhong Zhang,Shouling Ji,Yuan Tian,Binbin Zhao, Qinying Wang&a…

ubuntu 23.04 安装 中文输入法

1、安装 fcitx sudo apt install fcitxfcitx 安装好后,可以使用 fcitx-configtool 命令进行配置,其界面如下所示。在这里可以配置不同输入法的切换快捷键,默认输入法等。刚安装系统后,这里只有一个输入法,所以接下来要…

如何建立自己的会员系统_打造专属会员系统

打造专属会员系统,尊享无限特权与惊喜 在如今信息爆炸的时代,无论是线上还是线下,各种服务、产品层出不穷,如何才能在激烈的市场竞争中脱颖而出,吸引并留住客户呢?答案就是——建立自己的会员系统。今天&a…

北大核心期刊《思想政治课教学》投稿有什么要求?

北核《思想政治课教学》收职教、中专、大学、中小学,职称没要求,学生可以 探寻智慧之源,倾听思想之声,欢迎投稿《思想政治课教学》。我们致力于搭建一个开放、前沿的学术交流平台,汇聚国内外思想政治课教学的最新研究成…

AP AUTOSAR 执行管理的秘密揭晓

本文主要分享执行管理和状态管理以及操作系统接口模块,这些功能集群是Adaptive AUTOSAR的核心部分。你们可能会问,什么是执行管理和状态管理?它们是不是很复杂很高深?其实不然,它们就像是你的汽车的大脑和心脏,它们控制着你的汽车软件的启动、运行和停止,以及与你的汽车…

SecureCRT出现乱码的解决方法

SecureCRT是一个商业终端连接工具,它支持多种自定义设置。默认设置下,通过SecureCRT连接SSH服务器可能出现中文乱码的情况。这是由于SecureCRT字符编码与服务器的字符编码不一致造成的。 当然解决这个问题也很简单,将SecureCRT字符编码设置成…

【Python】成功解决NameError: name ‘sns‘ is not defined

【Python】成功解决NameError: name ‘sns’ is not defined 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您…

MTK安卓开发板_联发科开发板评估套件_安卓主板硬件开发

在介绍开发板之前,让我们先来区分一下核心板和开发板的区别。核心板是一种集成度高、功能完整的计算模块,搭载系统,简化了外围接口,体积尺寸相对较小,主要适用于嵌入式系统。而开发板由核心板底板组成,提供…

使用Barrier共享鼠标键盘,通过macos控制ubuntu系统

之前文章写过如何使用barrrier通过windows系统控制ubuntu系统,该文章将详细介绍如何使用barrier通过macos系统控制ubuntu系统 一、macOS安装barrier macOS版本barrier链接 1、双击点开安装包 2、将安装包里的barrier拷贝到macOS的达达->应用程序中 3、在达达…

奋斗不止,梦想不息——漫漫发展征途中的奋斗与追求

在人类历史的长河中,每一个辉煌的成就都凝聚着无数人的奋斗与努力。无论是科技的飞速进步,还是文化的灿烂繁荣,都离不开一代代人的坚持与拼搏。漫漫发展征途,惟有奋斗不辍,这一真理,深刻地揭示了人类社会发…