关于 内部类 你了解多少?(详解!!)

目录

1. 什么是内部类?

2. 内部类的分类 

3. 内部类

3.1 实例内部类

3.2 静态内部类 

4. 局部内部类 

5. 匿名内部类

 6.对象的打印


       “不积跬步无以至千里,不积小流无以成江海。”每天坚持学习,哪怕是一点点!!!

1. 什么是内部类?

在Java中,内部类是定义在其他类内部的类。它们的存在是为了提供更加灵活和功能强大的方式来组织和管理代码,从而使代码更加清晰和易于维护。当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。

public class OutClass {
    class InClass{

    }
} 

// OutClass是外部类
// InClass是内部类

 【注意事项】
 1. 定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类

public class A{

}

class B{

}

// A 和 B是两个独立的类,彼此之前没有关系

 2. 内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件

2. 内部类的分类 

先来看下,内部类都可以在一个类的哪些位置进行定义

public class OutClass {
    // 成员位置定义:未被static修饰 --->实例内部类
    public class InnerClass1{
    }


     // 成员位置定义:被static修饰 ---> 静态内部类
    static class InnerClass2{
    }


    public void method(){
    // 方法中也可以定义内部类 ---> 局部内部类:几乎不用
        class InnerClass5{
        }
    }
}

根据内部类定义的位置不同,一般可以分为以下几种形式:
      1. 成员内部类(普通内部类:未被static修饰的成员内部类 和 静态内部类:被static修饰的成员内部类)
      2. 局部内部类(不谈修饰符)、匿名内部类
注意:内部类其实日常开发中使用并不是非常多,大家在看一些库中的代码时候可能会遇到的比较多,日常开始中使用最多的是匿名内部类

3. 内部类

在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类

3.1 实例内部类

即未被static修饰的成员内部类。

public class OutClass {
    private int a;
    static int b;
    int c;

    public void methodA(){
        a = 10;
        System.out.println(a);
    }

    public static void methodB(){
        System.out.println(b);
    }

    // 实例内部类:未被static修饰
    class InnerClass{
        int c;
        public void methodInner(){

            // 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
            a = 100;
            b =200;
            methodA();
            methodB();

            // 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
            c = 300;
            System.out.println(c);

            // 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字
            OutClass.this.c = 400;
            System.out.println(OutClass.this.c);
        }
    }
    public static void main(String[] args) {
        // 外部类:对象创建 以及 成员访问
        OutClass outClass = new OutClass();
        System.out.println(outClass.a);
        System.out.println(OutClass.b);
        System.out.println(outClass.c);
        outClass.methodA();
        outClass.methodB();
        System.out.println("=============实例内部类的访问=============");
        // 要访问实例内部类中成员,必须要创建实例内部类的对象
        // 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
        // 创建实例内部类对象
        OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
        // 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
        OutClass.InnerClass innerClass2 = outClass.new InnerClass();
        innerClass2.methodInner();
    }
}

【注意事项】
1. 外部类中的任何成员都可以在实例内部类方法中直接访问
2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
 

3.2 静态内部类 

被static修饰的内部成员类称为静态内部类。 

public class OutClass {
    private int a;
    static int b;
    public void methodA(){
    a = 10;
    System.out.println(a);
}

public static void methodB(){
    System.out.println(b);
} 

// 静态内部类:被static修饰的成员内部类
static class InnerClass{
    public void methodInner(){
        // 在内部类中只能访问外部类的静态成员
        // a = 100; // 编译失败,因为a不是类成员变量
        b =200;
        // methodA(); // 编译失败,因为methodB()不是类成员方法
        methodB();
    }
}

public static void main(String[] args) {
    // 静态内部类对象创建 & 成员访问
    OutClass.InnerClass innerClass = new OutClass.InnerClass();
    innerClass.methodInner();
    }
}

 【注意事项】
1. 在静态内部类中只能访问外部类中的静态成员
2. 创建静态内部类对象时,不需要先创建外部类对象

4. 局部内部类 

定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。
 

public class OutClass {
    int a = 10;
    public void method(){
        int b = 10;
        // 局部内部类:定义在方法体内部
        // 不能被public、static等访问限定符修饰
        class InnerClass{
            public void methodInnerClass(){
                System.out.println(a);
                System.out.println(b);
            }
        } 
        // 只能在该方法体内部使用,其他位置都不能用
        InnerClass innerClass = new InnerClass();
        innerClass.methodInnerClass();
    }

    public static void main(String[] args) {
        // OutClass.InnerClass innerClass = null; 编译失败
    }
}

【注意事项】
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用
 

5. 匿名内部类

匿名内部类是指没有类名的内部类,通常在创建接口实例或继承抽象类时使用。它的语法结构如下:

new 父类构造器/接口() { 
    // 匿名内部类的类体,可以是成员变量、方法等
};

其中,父类构造器是指要继承的父类的构造方法,接口是指要实现的接口。在匿名内部类的类体中,可以定义成员变量、方法等,但不能有构造方法。

以下是一个示例,创建了一个实现了Runnable接口的匿名内部类:

Thread t = new Thread(new Runnable() {
    public void run() {
        System.out.println("Hello, World!");
    }
});
t.start();

在这个示例中,我们创建了一个Thread对象,并向它的构造方法中传入了一个实现了Runnable接口的匿名内部类。该匿名内部类实现了run方法,当线程启动后就会执行该方法,输出“Hello, World!”的信息。

 

 6.对象的打印

public class Person {
    String name;
    String gender;
    int age;

    public Person(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public static void main(String[] args) {
        Person person = new Person("Jim","男", 18);
        System.out.println(person);
    }

} 
// 打印结果:day20210829.Person@1b6d3586

 如果想要默认打印对象中的属性该如何处理呢?答案:重写toString方法即可。

public class Person {
    String name;
    String gender;
    int age;

    public Person(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    @Override
    public String toString() {
        return "[" + name + "," + gender + "," + age + "]";
    }

    public static void main(String[] args) {
        Person person = new Person("A小码","男", 18);
        System.out.println(person);
    }
}

//输出结果:[A小码,男,18]

 

( 注:图片来自网络,如有侵权,请联系删除 )  

希望对大家有所帮助,感谢观看!!!

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

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

相关文章

sqlserver配置管理器无法启动解决方案

在SQL server configuration manager配置管理器中遇到SQL server browser呈灰色,无法启动 右击选择属性 进入服务 将启动模式改为自动 可以启动了

Java面向对象2

代码块 代码块的构造顺序优先于构造器 细节

redis运维(七)基础通用命令

一 基础通用命令 备注: 与具体数据类型无关Tab键 自动补全补充: redis 命令是不区分大小写 通用不到 10 个提升逼格的 redis 命令 后续: slowlog、rename-command、monitor、set ① help command 需求: 显示有关redis命令的…

DVWA - 4

文章目录 JavaScriptlowmedium JavaScript 前端攻击。token 不能由前端生成,js 很容易被攻击者获取,从而伪造 token。同样其他重要的参数也不能由前端生成。 low 不修改输入,点击提交报错: 根据提示改成 success,还是报错&…

趣学python编程 (一、计算机基础知识科普)

未来是高度科技化和智能化的时代。过去不识字的叫“文盲”,如今不懂点计算机知识,则可能是新时代的“文盲”。不论从事什么行业,了解下计算机和编程都是有益的。Python 连续多年占据最受欢迎的编程语言榜首,未来Python有机会成为像…

C++之异常处理

目录 一、C语言处理错误 1、终止程序 2、返回错误码 二、C异常 异常的抛出和匹配原则 异常安全 异常规范 异常优缺点 一、C语言处理错误 传统处理错误的两种方式: 1、终止程序 使用assert是直接终止程序,包含头文件assert.h即可 缺点&#xf…

NEFTune: 通过简单的噪声提升指令精调效果

NEFTune指的是Noise Embedding Finetuning(噪声嵌入精调),提出自论文:NEFTune: NOISY EMBEDDINGS IMPROVE INSTRUCTION FINETUNING。 NEFTune方法的原理仅使用一句话就可以描述清楚:在finetune过程的词向量中引入一些…

众安保险面试题

文章目录 1.说一下Java内存模型?2.List、Set、Map的区别?3.介绍一下设计模式?4.MySQL存储结构?5.索引失效的场景?6.为什么使用函数索引会失效?7.Spring事务有哪两种?7.1 编程式事务@RestController7.2 声明式事务8.@Transactional实现原理?9.事务如何合并@Transactiona…

es head 新增字段、修改字段、批量修改字段、删除字段、删除数据、批量删除数据

目录 一、新增字段 二、修改字段值 三、批量修改字段值 ​四、删除字段 五、删除数据/文档 六、批量删除数据/文档 一、新增字段 put http://{ip}:{port}/{index}/_mapping/{type} 其中,index是es索引、type是类型 数据: {"_doc"…

听GPT 讲Rust源代码--library/core/src(7)

题图来自 Hello, crustaceans.[1] File: rust/library/core/src/ptr/metadata.rs 在Rust的源代码中,rust/library/core/src/ptr/metadata.rs 文件的作用是定义了与指针(ptr)和元数据(metadata)相关的结构体和 trait&am…

C#源代码生成器深入讲解二

在阅读本文前需掌握源代码生成器相关知识C#源代码生成器深入讲解一 C#源代码生成器深入讲解二—增量生成器 源代码生成器有个非常大的弊病,每次都会遍历所有的语法树来分析,这样就有个问题,每次可能只修改了很少一部分或者只有很少一部分的代码需要分析…

异行星平台--CRM系统搭建

使用异行行低代码平台搭建的CRM系统。CRM系统中,包括“客户”、“商机”、“合同”、“回款”、“开票”、“营销”、“回访”、“产品”、“联络人”、“销售订单”、“线索”。 “管理后台”可能是指一个用于管理后台系统的应用,可能包括对各种功能和数…

基于django电影推荐系统

基于django电影推荐系统 摘要 该Django电影推荐系统是一个简单而基础的框架,旨在展示系统的基本组件。系统包括两个主要模型,即Movie和Rating,用于存储电影信息和用户评分。视图层包括展示电影列表和电影详情的功能,使用模板进行页…

从底层认识哈希表【C++】

目录 一. unordered系列关联式容器 二. unordered_map的文档介绍 接口使用 三. 底层实现 (1)哈希概念 例: (2)哈希冲突 (3)冲突解决 1.闭散列​​​​​​​ 闭散列框架 插入 查找 删除 2.开散…

虾皮店铺所有商品数据接口(shopee.item_search_shop)

虾皮店铺所有商品数据接口可以提供丰富的电商数据,包括商品数据、订单数据、会员数据、评价数据等。以下是具体的介绍: 商品数据:虾皮提供了商品的基本信息,包括商品名称、描述、规格、价格、销量、库存等信息。此外,…

【网络知识必知必会】再谈Cookie和Session

文章目录 前言1. 回顾 Cookie1.1 到底什么是 CookieCookie 的数据从哪里来Cookie 的数据长什么样Cookie 有什么作用Cookie 到哪里去Cookie 怎么存储的 2. 理解 Session3. Cookie 和 Session 的区别总结 前言 在讲 HTTP 协议时, 我们就谈到了 Cookie 和 Session, 当时我们只是粗…

【部署篇】Docker配置MySQL容器+远程连接

一、前言 上篇文章在部署nestjs时,由于docker访问不了主机的localhost,所以无法连接主机数据库。所以我们只能在docker中额外配置一个数据库,映射到主机上,然后可以通过ip地址访问。 在本篇文章我们会在docker中创建一个mysql&a…

Logback 日志格式参数说明

打印日志格式&#xff1a; <property name"LOG_PATTERN" value"[${APP_NAME} ${SERVER_IP}:${SERVER_PORT}] %d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%X{traceId}-%X{spanId}] [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/&g…

这7个“小毛病”项目经理必须克服

大家好&#xff0c;我是老原。 项目经理干项目可能不在行&#xff0c;但“踩坑”、“背锅”一定在行。 当上项目经理不容易&#xff0c;当好项目经理更不容易&#xff0c;有永远填不完的坑和背不完的锅。 如果要问项目经理都踩过哪些坑&#xff0c;那真的是太多了&#xff0…

【邻接表,图的邻接表存储表示】

文章目录 邻接表无向图有向图图的邻接表存储表示&#xff1a;图的邻接表的弧&#xff08;边&#xff09;的结点结构 邻接矩阵的好处&#xff1a; 1.直观&#xff0c;简单&#xff0c;好理解。 2.方便检查任意一对顶点间是否存在边 3.方便找到任一顶点的所有“邻接点”&#xff…