4.9 内部类

news2025/7/19 6:07:43

文章目录

  • 1.内部类概述
  • 2.特点
  • 3.练习 : 内部类入门案例
  • 4.成员内部类
    • 4.1 练习 : 被private修饰
    • 4.2 练习 : 被static修饰
  • 5.局部内部类
  • 6.匿名内部类


1.内部类概述

如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。
就是把类定义在类的内部的情况就可以形成内部类的形式。
A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待
在这里插入图片描述

2.特点

  1. 内部类可以直接访问外部类中的成员,包括私有成员
  2. 外部类要访问内部类的成员,必须要建立内部类的对象
  3. 在成员位置的内部类是成员内部类
  4. 在局部位置的内部类是局部内部类

3.练习 : 内部类入门案例

package partFour;
/*本类用作内部类的入门案例*/
public class TestInner1 {
    public static void main(String[] args) {
        //3.1创建内部类的对象,使用内部类的资源
        /*外部类名.内部类名 对象名=外部类对象.内部类对象*/
        Outer.Inner oi = new Outer().new Inner();
        //3.2通过创建好的内部类对象,使用内部类的资源
        oi.delete();
        System.out.println(oi.sum);
        //3.3外部想要使用外部类的资源,需要用过外部类的对象
        new Outer().play();
    }
}

//1.创建外部类
class Outer{
    //1.1创建外部类的成员变量
    String name;
    private int age;
    //1.2创建外部类的成员方法
    public void play(){
        System.out.println("Outer...play()");
        //5.外部类使用内部类资源
        //delete(); //不可以直接调用内部类的方法
        //System.out.println(sum);//不能直接查看内部类的属性
        /*外部类如果想要使用内部类的资源,必须先创建内部类的对象
         * 通过内部类对象调用内部类的功能*/
        Inner in = new Inner();//直接创建内部类对象,无需指定外部类,已经在外部类里了
        System.out.println(in.sum);//通过内部类对象查看内部类的属性
        in.delete();//通过内部类对象调用内部类的方法
    }
    //2.创建内部类--被看做外部内的特殊成员
    class Inner{
        //2.1 定义内部类的成员变量
        int sum = 10;
        //2.2 定义内部类的成员方法
        public void delete(){
            System.out.println("Inner...delete()");
            //4.测试内部类能否使用外部类的资源
            //play();//可以调用外部类的方法
            /*要注意,play与delete只能同时调用一个,不然外部类与内部类容易形成死循环*/
            System.out.println(name);//可以查看外部类的普通属性
            System.out.println(age);//可以查看外部类的私有属性
        }
    }
}

4.成员内部类

4.1 练习 : 被private修饰

package partFour;
/*本类用于测试成员内部类被private修饰*/
public class TestInner2 {
    public static void main(String[] args) {
        //4.创建内部类对象
        //Outer2.Inner2 oi = new Outer2().new Inner2();
        //oi.eat();
        /*如果成员内部类被private修饰,外部无法直接访问,或创建内部类的对象*/
        //7.间接访问,虽然创建不了私有内部类的对象,但是可以创建外部类的对象
        new Outer2().getInner2Eat();
    }
}

//1.创建外部类
class Outer2{
    //6.提供一个公共的方法,在方法内部创建内部类Inner2的对象,调用内部类的功能
    public void getInner2Eat(){
        Inner2 in = new Inner2();//可以在外部类里创建私有成员内部类的对象
        in.eat();//通过创建好的内部类对象调用内部类的功能
    }
    /*成员内部类的位置在类里方法外*/
    public Object Inner2;

    //2.创建成员内部类Inner2
    private class Inner2{
        //3.创建成员内部类的普通方法
        public void eat(){
            System.out.println("Inner...eat()");
        }
    }
}

总结:
成员内部类被Private修饰以后,无法被外界直接创建创建对象使用
所以可以创建外部类对象,通过外部类对象间接访问内部类的资源

4.2 练习 : 被static修饰

package partFour;
/*本类用于测试成员内部类被static修饰*/
public class TestInner3 {
    public static void main(String[] args) {
        //4.1创建内部类对象,访问内部类资源 方式一
        //Outer3.Inner3 oi = new Outer3().new Inner3();
        //oi.show();//Inner3...show()
        //4.2创建内部类匿名对象访问内部类资源 方式二
        //new Outer3().new Inner3().show();//Inner3...show()

        /*现象:当内部类被static修饰以后,new Outer3报错,注释掉上面的代码*/
        //6.1由于内部类是静态的,所以可以通过外部类类名直接找到,不用创建外部类对象
        Outer3.Inner3 oi = new Outer3.Inner3();
        oi.show();
        //6.2静态成员内部类创建匿名对象
        new Outer3.Inner3().show();

        //8.1调用内部类的静态方法:方式一  不推荐
        new Outer3.Inner3().show2();
        //8.1调用内部类的静态方法:方式二
        /*没有创建任何一个对象,直接都是通过类名找到的静态资源
         * 像这样连着点的方式,称作:链式加载*/
        Outer3.Inner3.show2();
    }
}

//1.创建外部类
class Outer3{
    //2.创建成员内部类
    //5.用static修饰成员内部类
    static class Inner3{
        //3.定义成员内部类的普通方法
        public void show(){
            System.out.println("Inner3...show()");
        }
        //7.创建一个静态成员内部类中的静态方法
        static public void show2(){
            System.out.println("Inner...show2()");
        }
    }
}

总结:
静态资源访问时不需要创建对象,可以通过类名直接访问
访问静态类中的静态资源可以通过”. . . ”链式加载的方式访问

5.局部内部类

package partFour;
/*本类用于测试局部内部类*/
public class TestInner4 {
    public static void main(String[] args) {
        //5.创建外部类的对象,调用外部类的show方法
        new Outer4().show();
        //new Outer4().new Inner4();//会报错
        /*如何使用局部内部类的资源呢?
         * 创建外部类对象调用外部方法或者直接在main()创建局部内部类对象都是不可行的
         * 需要在外部类中创建内部类的对象,并且调用内部类的方法,才会触发内部类的功能*/

    }
}

//1.创建外部类
class Outer4{
    //2.创建外部类成员方法
    public void show(){
        System.out.println("Outer...show()");
        /*局部内部类的位置:在方法里*/
        //3.创建局部内部类
        class Inner4{
            //4.创建局部内部类的资源
            String name;
            int age;
            public void eat(){
                System.out.println("Inner...eat()");
            }
        }
        /*如何使用局部内部类的资源*/
        //6.在show()里面创建内部类对象,调用内部类的功能
        Inner4 in = new Inner4();
        in.eat();
        System.out.println(in.name);
        System.out.println(in.age);
    }
}

6.匿名内部类

package partFour;
/*本类用于测试匿名内部类
 * 匿名内部类没有名字,通常与匿名对象结合在一起使用*/
public class TestInner5 {
    public static void main(String[] args) {
        //传统方法:创建接口的实现类+实现类实现类实现接口中的抽象方法+创建实现类对象+通过对象调用方法
        //3.创建接口一对应的匿名对象与匿名内部类new Inter1(){}.save;,并调用实现了的方法save
        new Inter1() {
            @Override
            public void save() {
                System.out.println("save()...");
            }

            @Override
            public void get() {    }
        }.save();

        //5.创建抽象类对应的匿名对象与匿名内部类
        new Inter2(){//抽象类不能实现抽象方法,所以只实现了未实现的方法
            @Override
            public void drink() {
                System.out.println("一人我饮酒醉");
            }
        }.drink();

        //7.调用普通类的功能调用,创建匿名对象直接调用
        new Inter3().powerUP();
        new Inter3().powerUP();//new了俩次,所以是俩个匿名对象

        /*如果想要多次使用实现后的功能,还是要创建普通的对象
         * 匿名对象只能使用一次,一次只能调用一个功能
         * 匿名内部类其实就充当了实现类的角色,去实现未实现的抽象方法,只是没有名字而已*/
        Inter3 in = new Inter3();
        in.study();
        in.study();
        in.study();
        in.study();
    }
}

//1.创建接口
interface Inter1{
    //2.定义接口中的抽象方法
    void save();
    void get();
}
//4.创建抽象类
abstract class Inter2{
    public void play(){
        System.out.println("Inner...play()");
    }
    abstract public void drink();
}
//6.创建普通类
class Inter3{
    public void study(){
        System.out.println("什么都阻挡不了我学习");
    }
    public void powerUP(){
        System.out.println("我们会越来越强的");
    }
}

总结:
匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MQ中间件概念一览

一、概述 1. 大多应用中,可通过消息服务中间件来提升系统异步通信、扩展解耦能力 2. 消息服务中两个重要概念: 消息代理(message broker)和目的地(destination) 当消息发送者发送消息以后,将由…

有了ChatGPT 微软对元宇宙不香了?

押注ChatGPT是微软最近的主要发力点,另一边,它开始向元宇宙业务挥出裁员“大刀”。海外消息称,微软解散了成立仅四个月的工业元宇宙团队,约100名员工被全被解雇。 这只是微软放缓元宇宙战略的长尾动作,此前&#xff0…

【MFC】模拟采集系统——界面设计(17)

功能介绍 启动界面 开始采集: PS:不涉及 数据保存,重现等功能 界面设计 界面分为三块:顶部黑条带关闭按钮、左边对话框,右边的主界面 资源: 顶部黑条 top.bmp 2* 29 (宽 * 高 像素点&…

SAS应用入门学习笔记7

代码说明: 1)distinct 想获得region变量有的多少种? 2)如果是常规语句,我们是使用proc freq 语句: where for filter: 然后有一个escape语句的概念: 这是一个简单的语法&#xff…

Redis集群离线安装

近日,由于客户的系统运行环境在一个封闭的网络内,不能与互联网联通,也不能提供yum库,所以运行环境只能采用离线安装的方式,我总结了一下本次的安装经过,希望对需要的人有所帮助。一、安装gcc查看gcc版本要求…

牛客网Python篇数据分析习题(五)

1.现有牛客网12月每天练习题目的数据集nowcoder.csv。包含如下字段(字段之间用逗号分隔): user_id:用户id question_id:问题编号 result:运行结果 date:练习日期 请你统计答对和答错的总数分别是多少。 imp…

态路小课堂丨下一代数据中心100G接口第二篇——SFP-DD封装

100G光模块根据封装模式可分为QSFP28、CXP、CFP、CFP2、FCP4、DSFP和SFP-DD等。态路小课堂之前已经大量介绍了相关内容(。 态路小课堂丨下一代数据中心100G接口——DSFP态路小课堂丨100G解决方案-425G NRZ光模块态路小课堂丨什么是100G QSFP28单波光模块&#xff1f…

为什么要用springboot进行开发呢?

文章目录前言1、那么Springboot是怎么实现自动配置的1.1 启动类1.2 SpringBootApplication1.3 Configuration1.4 ComponentScan1.5 EnableAutoConfiguration1.6 两个重要注解1.7 AutoConfigurationPackage注解1.8 Import(AutoConfigurationImportSelector.class)注解1.9自动配置…

素数相关(结合回文数,合数)线性筛素数(欧拉筛法)Euler【算法模板笔记】

一、朴素筛法(埃拉托斯特尼筛法)Eratosthenes 筛法(埃拉托斯特尼筛法,简称埃氏筛法)时间复杂度是O(nloglogn)不常用,被欧拉筛代替,略二、线性筛素数(欧拉筛法)简介线性筛…

C++007-C++循环结构

文章目录C007-C循环结构for循环for循环举例for循环格式题目描述 输出十次手机号题目描述 打印区间内的整数题目描述 打印字符之间的所有字符题目描述 打印区间内符合条件的整数数数量作业在线练习:总结C007-C循环结构 在线练习: http://noi.openjudge.cn…

HappyAI 算法任务调度平台 - 开篇

HappyAI 算法任务调度平台 - 开篇 HappyAI 算法任务调度平台 - 接入 HappyAI 算法任务调度平台 - 开发 1. 支持不同算法侧接入即算法集群(如:paddle算法平台;mmdetection算法平台) 2. 支持不同相机取流(如&#xff…

启动您的 MySQL 查询:ChatGPT 如何帮助您检索 MySQL 数据

本文涉及到的相关软件,dbForge Studio for MySQL和ChatGPT,在您尝操作前,请务必先确保两个程序都正常运作哦,废话不多说,开始上干货! Devart 提供包括Oracle、SQL Server、MySQL、PostgreSQL、InterBase以及Firebird在…

msvcr120.dll下载官网,如何处理msvcr120.dll丢失

msvcr120.dll下载官网?目前msvcr120.dll是没有官网的!MSVCR120.dll是Microsoft Visual C Redistributable安装程序的一部分,通常在运行依赖于Visual C库的应用程序时需要该文件。所以不要相信网上那些写着所谓的官网,下面给大家分…

Sentinel源码阅读

基础介绍 Sentinel 的使用可以分为两个部分: 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配&…

电子纸墨水屏的现实应用场景

电子纸挺好个东西,大家都把注意力集中在商超场景 其实还有更多有趣的场景方案可用,价值也不小,比如: 一、仓库场景 通过亮灯拣选,提高仓库作业效率 二、仓库循环使用标签 做NFC类发卡式应用,替代传统纸…

Python中ArcPy将多张栅格图像分割为多个网格小块的方法

本文介绍基于Python中的ArcPy模块,依据渔网的矢量数据文件或通过手动划分小方格的方法,批量将大量栅格图像分割为多个矩形小栅格的方法。 首先明确一下我们的需求。现有同一区域内的多张栅格遥感影像,我们希望对于每一景栅格遥感影像而言&…

QML- 信号和事件系统

QML- 信号和事件系统一、概述二、信号事件处理系统使用1. 用信号处理器接收信号2. 信号处理程序3. 使用Connections 类型4. 附加信号处理程序三、向自定义QML类型添加信号四、将信号连接到方法和信号1. 信号与信号的连接一、概述 应用程序和用户界面组件需要相互通信。例如&am…

数据迁移——技术选型

日常我们在开发中,随着业务需求的变更,重构系统是很常见的事情。重构系统常见的一个场景是变更底层数据模型与存储结构。这种情况下就要对数据进行迁移,从而使业务能正常支行。 背景如下:老系统中使用了mongo数据库,由…

webpack 的热更新是如何做到的?原理是什么?

Hot Module Replacement,简称 HMR,在不需要刷新整个页面的同时更新模块,能够提升开发的效率和体验。热更新时只会局部刷新页面上发生了变化的模块,同时可以保留当前页面的状态,比如复选框的选中状态等。 在 webpack 中…

Maxwell工作流程详解

要介绍maxwell的工作原理,首先需要讲一下mysql主从复制的原理 mysql主从复制原理: 如上图,左边是master主节点,右边是slave从节点 工作流程: 1.往主节点mysql的数据库中写入数据,产生数据变化&#xff0c…