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); //根据就近原则,访问了局部内部类中的n1
                    System.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
                @Override
                public 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.返回一个匿名内部类的对象
                //这个匿名内部类继承了抽象类则需要重写抽象方法
                @Override
                public 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类
                @Override
                public 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() {
            @Override
            public 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() {
                @Override
                public void ring() {
                    System.out.println("懒猪起床了");
                }
            });
            new CellPhone().alarmclock(new Bell() {
                @Override
                public 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文浅谈射频识别RFID

RFID,全称为Radio Frequency Identification,即射频识别,是一种通过无线电信号识别特定目标并读取相关数据的技术。这种技术利用射频信号及其空间耦合、传输特性,实现对静止或移动物品的自动识别。 RFID由以下2个部分组成&#xf…

MongoDB从0到1:高效数据使用方法

MongoDB,作为一种流行的NoSQL数据库。从基础的文档存储到复杂的聚合查询,从索引优化到数据安全都有其独特之处。文末附MongoDB常用命令大全。 目录 1. 引言 MongoDB简介 MongoDB的优势和应用场景 2. 基础篇 安装和配置MongoDB MongoDB基本概念 使…

vue3.x项目,配置项目打包到二级目录

vue3.x项目,配置项目打包到二级目录 一、打开 vite.config.js 文件,添加或修改base字段, 将其值设置为二级目录的路径。例如想将应用部署到服务器上的/my-app目录下,如下设置: export default defineConfig({base: /…

滴滴 Flink 指标系统的架构设计与实践

毫不夸张地说,Flink 指标是洞察 Flink 任务健康状况的关键工具,它们如同 Flink 任务的眼睛一般至关重要。简而言之,这些指标可以被理解为滴滴数据开发平台实时运维系统的数据图谱。在实时计算领域,Flink 指标扮演着举足轻重的角色…

【C++基础】1.认识C++——《跟老吕学C++编程语言》

【C基础】1.认识C——《跟老吕学C编程语言》 认识CC简介C发展历程C四大特性支持数据封装和数据隐藏抽象支持继承和重用支持多态性 C语言工作原理C语言标准C标准库 认识C C简介 C,全称是C Plus Plus。老吕比较喜欢叫它C加加。 C是C语言的继承;C是是编译式…

(免费分享)基于springboot停车场管理平台(修复版)

修复百度车牌识别、修改样式、已知一些bug等 仅供学习交流,请勿随意传播,否则后果自负!! 仅供学习交流,请勿随意传播,否则后果自负!! 仅供学习交流,请勿随意传播,否则后果自负!! 角色: 超级…

Node.js入门基础—day01

个人名片: 😊作者简介:一名大二在校生 🤡 个人主页:坠入暮云间x 🐼座右铭:给自己一个梦想,给世界一个惊喜。 🎅**学习目标: 坚持每一次的学习打卡 文章目录 初识node.js什…

【LeetCode热题100】73. 矩阵置零(矩阵)

一.题目要求 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 二.题目难度 中等 三.输入样例 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0…

python学习2:日志记录的用法

一些日志记录的简单记录: 用basicConfig可以进行配置 注意日志的等级: 上述代码得到的日志如下(最基础的日志): 关于记录下来的日志格式可以有很多内容:如等级、发生的时间、发生的位置、发生的进程、…

《安富莱嵌入式周报》第334期:开源SEM扫描电子显微镜,自制编辑器并搭建嵌入式环境,免费产品设计审查服务,实用电子技术入门,USB资料汇总,UDS统一诊断

周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: https://www.bilibili.com/video/BV1om411Z714/ 《安富莱嵌入式周报》第334期:开源SEM…

如何注册Devin-首个全自主AI软件工程师

最近devin大火,具体的就不说了,大家应该都知道,写代码非常nb,这里说一下devin的注册方式,目前devin的内测已经开启。 官网https://www.cognition-labs.com/blog注册网址Your reliable AI software engineerhttps://pr…

55. 跳跃游戏(力扣LeetCode)

文章目录 55. 跳跃游戏贪心每一次都更新最大的步数 取最大跳跃步数(取最大覆盖范围) 55. 跳跃游戏 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后…

【数理统计实验(三)】假设检验的R实现

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…

python基于flask考研学习交流系统30vy7附源码django

考研在线学习与交流平台根据实际情况分为前后台两部分,前台部分主要是让用户使用的,包括用户的注册登录,首页,课程信息,在线讨论,系统公告,后台管理,个人中心等功能;后台…

OpenCV filter2D函数详解

OpenCV filter2D函数简介 OpenCV filter2D将图像与内核进行卷积,将任意线性滤波器应用于图像。支持就地操作。当孔径部分位于图像之外时,该函数根据指定的边界模式插值异常像素值。 该函数实际上计算相关性,而不是卷积: filter…

python爬虫(9)之requests模块

1、获取动态加载的数据 1、在开发者工具中查看动态数据 找到csdn的门户的开发者工具后到这一页面。 2、加载代码 import requests headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36…

数据仓库为什么要分层建设?每一层的作用是什么?

在数字化时代,数据已成为企业最宝贵的资产之一。为了更好地管理和利用这些数据,许多企业都建立了数据仓库。然而,数据仓库并非简单的数据存储工具,而是一个复杂的数据处理和分析系统。其中,分层建设是数据仓库设计的重…

第六篇【传奇开心果系列】Python的自动化办公库技术点案例示例:大学生数据全方位分析挖掘经典案例

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas库全方位分析挖掘大学生数据能力介绍二、大学生学生成绩数据分析数据挖掘示例代码三、大学生选课数据分析数据挖掘示例代码四、大学生活动参与数据分析数据挖掘示例代码五、大学…

如何在 Azure 上备份 windows 虚拟机并恢复

起因 Azure 在 windows 虚拟机备份/还原上和通常的虚拟机备份有所区别,一般的虚拟机备份在控制台的上的操作通常是选择将目标虚拟机备份成镜像,还原的时候选择备份好的镜像即可。 但是对于 windows 虚拟机的备份/还原需要借助其磁盘进行操作。下面是操…

MySQL学习Day32——数据库备份与恢复

在任何数据库环境中,总会有不确定的意外情况发生,比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的,这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时,会出现主从服…