内部类之成员内部类

news2024/11/20 2:40:14

我们在阅读源码的过程中,会遇到很多内部类,让我们阅读难度增加。这篇文章主要介绍成员内部类的作用

1.成员内部类可以访问外部类的所有方法和成员变量(不论是静态的还是非静态的)

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: 成员内部类: 不可以有静态成员变量,但是可以反问外部类的任何(静态和非静态的)成员变量和方法
 *
 * 可以无条件地访问外围类的所有元素
 * 为什么可以引用:内部类虽然和外部类写在同一个文件中, 但是编译完成后, 还是生成各自的class文件,内部类通过this访问外部类的成员。
 * 编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象(this)的引用;
 * 编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为内部类中添加的成员变量赋值;
 * 在调用内部类的构造函数初始化内部类对象时,会默认传入外部类的引用。
 * @date 2023/6/28 16:36
 */
public class MemberInnerClass_1 {
    private static String name="外部类的静态变量";
    private String value="外部类的非静态变量";

    private static void m1(){
        System.out.println("外部类的静态方法");
    }

    private void m2(){
        System.out.println("外部类的非静态方法");
    }

    public static String getName() {
        return name;
    }

    public static void setName(String name) {
        MemberInnerClass_1.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    private class InnerClass{
        public InnerClass(){
        }

        public void out(String name1,String value1){
            System.out.println(name);
            System.out.println(value);
            name=name1;
            value=value1;
            System.out.println(name);
            System.out.println(value);
            m1();
            m2();
        }
    }

    public static void main(String[] args) {

        //内部类创建实例的方式
        InnerClass innerClass1 = new MemberInnerClass_1().new InnerClass();
        MemberInnerClass_1 memberInnerClass11 = new MemberInnerClass_1();
        InnerClass innerClass2 = memberInnerClass11.new InnerClass();

        innerClass2.out("内部类修改了外部类的静态变量","内部类修改了外部类的非静态变量");
    }
}

运行结果:
在这里插入图片描述

成员内部类可以对同一包下的其他类隐藏

成员内部类的修饰符: private protected, defaule, public`
首先我们定义一个接口

public interface TestInterface{
    void test();
}

定义一个内部类实现上面的接口,注意内部类用private修饰符修饰,这样可以防止其他的类的访问;外部类提供获取内部类实例的方法,返回值类型是接口类型

/**
 * @author yangmin
 * @version 1.0
 * @description: 测试内部类对同一包下的类做隐藏
 * @date 2023/6/29 10:06
 */
public class MemberInnerClass_2 {

    public TestInterface getInner() {
        return new Inner();
    }

  private  class Inner implements TestInterface {

        @Override
        public void test() {
            System.out.println("我是MemberInnerClass_2的内部类");
        }
    }
}

在同一个包下新建一个类进行访问

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: TODO
 * @date 2023/6/29 10:18
 */
public class Test2 {
    public static void main(String[] args) {
        MemberInnerClass_2 memberInnerClass2 = new MemberInnerClass_2();
        TestInterface testInterface = memberInnerClass2.getInner();
        testInterface.test();
    }
}

测试结果:
在这里插入图片描述
分析: private修饰符修饰内部类使得外部类无法通过外部类访问, 实现接口并且外部类提供了返回内部类的方法,但是返回类型是内部类实现的接口类型,当外部类通过该方法时获取的是接口类型, 实现了内部类的隐藏

可以解决单继承的问题

首先我们定义两个父类

public class FuOne {
    void m(){
        System.out.println("FuOne的方法");
    }
}


public class FuTwo {
    void m(){
        System.out.println("FuTwo的方法");
    }
}

定义一个外部类和两个内部类,并让这两个内部类分别继承上面的父类

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: TODO
 * @date 2023/6/29 10:55
 */
public class MemberInnerClass_3 {

    private class SunOne extends FuOne{

    }

    private class SunTwo extends FuTwo{

    }

    public void m1(){
        new SunOne().m();
    }

    public void m2(){
        new SunTwo().m();
    }
}

测试类及结果

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: TODO
 * @date 2023/6/29 10:18
 */
public class Test2 {
    public static void main(String[] args) {
       MemberInnerClass_3 memberInnerClass3 = new MemberInnerClass_3();
        memberInnerClass3.m1();
        memberInnerClass3.m2();
    }
}

结果:
在这里插入图片描述

补充

  • 成员内部类不能定义静态变量和静态方法, 可以反问外部类的任何的方法和变量
  • 内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的
  • 创建内部类的方法
public class ClassOuter {
    public void fun(){
        System.out.println("外部类方法");
    }
    public class InnerClass{  
    }
}

public class TestInnerClass {
    public static void main(String[] args) {
        //创建方式1
        ClassOuter.InnerClass innerClass = new ClassOuter().new InnerClass();
        //创建方式2
        ClassOuter outer = new ClassOuter();
        ClassOuter.InnerClass inner = outer.new InnerClass();
    }
}

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

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

相关文章

如何让chatgpt给我们实现一个桌面便签?

我: 用Java开发一款桌面便签软件。功能需求:1、便签可以钉在桌面任意角落;2、便签内容实时保存到本地;3、有新增按钮,点击新增时清除当前面板上的内容,新建一条新的便签内容,并保存到本地&#…

通往AGI之路:揭秘英伟达A100、A800、H800、V100在高性能计算与大模型训练中的霸主地位

AGI | NLP | A100 | H100 | Nvidia | Aurora GPT| LLM | A800 | V100 | Intel | ChatGPT 日前,随着深度学习、高性能计算、大模型训练等技术的保驾护航,通用人工智能时代即将到来。各个厂商也都在紧锣密鼓的布局,如英伟达前段时间发布GH 200…

C3.ai:一个即将“破灭”的人工智能泡沫

来源:猛兽财经 作者:猛兽财经 C3.ai仅适用于能承受高风险波动的投资者 猛兽财经曾在之前分析过C3.ai(AI)这家公司,认为C3.ai可能在借助人工智能热潮炒作自己。截止撰写本文时,C3.ai的股价已跌到了到2…

使用ganymed-ssh2连接linux报错 Cannot negotiate, proposals do not match

ganymed-ssh2连接linux报错 背景报错信息解决方案:运行成功 背景 最近有个项目,需要在Linux下的服务器内写了一部分Python脚本,业务处理却是在Java内,那么就想能不能在Java里面,来远程执行Linux下的Python脚本&#x…

chatgpt赋能python:使用Python连接网络摄像头

使用Python连接网络摄像头 网络摄像头是现代生活中不可或缺的设备之一,其允许用户在远程位置查看实时视频流。Python语言提供了强大的工具来连接和控制网络摄像头。本文将向您展示如何使用Python连接网络摄像头以及如何将视频流数据流式传输到本地计算机。 环境设…

【AUTOSAR】BMS开发实际项目讲解(十九)----电池管理系统系统设计电池单体过放后再充电保护

电池单体过放后再充电保护 关联的系统需求 TSR-BMS-2101、TSR-BMS-2102、TSR-BMS-2103、TSR-BMS-2104、TSR-BMS-2105、TSR-BMS-2106、TSR-BMS-2107、TSR-BMS-2108、TSR-BMS-2109、TSR-BMS-2110、TSR-BMS-2111、TSR-BMS-2112、TSR-BMS-2113、TSR-BMS-2114、TSR-BMS-2115、TSR-B…

七年老Android推荐 : 日常开发中好用的工具 (一)

1. 前言 作为一名拥有七年经验的Android开发工程师,在日常开发中,总希望能提升自己的开发效率,对此也积累了一些工具,本文对此总结了一些好用的工具。 2. 视频转GIF工具 我们在写博客的时候,常常要录屏,…

leetcode:2000. 反转单词前缀(python3解法)

难度:简单 给你一个下标从 0 开始的字符串 word 和一个字符 ch 。找出 ch 第一次出现的下标 i ,反转 word 中从下标 0 开始、直到下标 i 结束(含下标 i )的那段字符。如果 word 中不存在字符 ch ,则无需进行任何操作。…

智云通CRM:在谈判中如何避免被客户利用的陷阱?

智云通CRM系统是一款专业的客户关系管理系统,帮助企业实现客户管理的数字化转型。在日常销售工作中,销售人员经常会面临各种问题和质疑,良好的应对技巧和回答方法对于维护好客户关系、促成交易非常重要。下面将介绍一些经常会被客户问到的问题…

从源码全面解析 dubbo 服务端服务调用的来龙去脉

👏作者简介:大家好,我是爱敲代码的小黄,独角兽企业的Java开发工程师,CSDN博客专家,阿里云专家博主📕系列专栏:Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

echatrs-地图,根据数据进行点状显示和指向

echarts地址:https://www.makeapie.cn/echarts var data2 [{ name: 海门, value: 9 },{ name: 鄂尔多斯, value: 12 },{ name: 招远, value: 12 },{ name: 舟山, value: 12 },{ name: 齐齐哈尔, value: 14 },{ name: 盐城, value: 15 },{ name: 赤峰, value: 16 },…

JMeter 后置处理器之JSON提取器

目录 前言: 测试环境 插件介绍 插件参数 插件使用示例 JSON-PATH表达式介绍 操作符 函数 过滤器操作符 JSON PATH示例 前言: JMeter是一个功能强大的性能测试工具,它提供了许多后置处理器来处理和提取测试结果。其中一个常用的后…

【强化学习】常用算法之一 “PPO”

作者主页:爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

Android 操作系统日历完成提醒功能 附带开关闹钟 适配高版本安卓

Android 操作系统日历完成提醒功能 附带开关闹钟 如果想要一个稳定且不用担心生命周期的提醒方式,可以试试利用系统日历去完成任务的提醒或某个活动的预约。 项目仓库地址在文末 环境 Java 11 Android sdk 30 Gredle 7.1 minSdkVersion 23 targetSdkVersion 30测…

js 纯前端实现 重新部署 通知用户刷新网页

需求:有时候上完线,用户还停留在老的页面,用户不知道网页重新部署了,跳转页面的时候有时候js连接hash变了导致报错跳不过去,并且用户体验不到新功能,需要进行优化,每当打包发版后客户进入系统就…

F#奇妙游(1):F#浅尝

F#奇妙游(1):F#浅尝 是什么 F#是.NET平台的OCaml。 这句话很欠打,.NET和OCaml前者知道的人有一些,后者就很少了。.NET平台是一个开源的软件平台,早期由微软主导,目前已经开源,由.…

如何使用CSS Grid 居中 div

本文翻译自 How to Center a Div Using CSS Grid,作者:Fimber Elemuwa, Ralph Mason。 略有删改 在本文中,我们将介绍使用CSS Grid在水平和垂直方向上居中div的五种方法,当然这些技术可用于任何类型的元素。 初始化 我们首先创建…

ASP.Net Core Web API项目发布到IIS(二)

目录 一.启动并配置IIS环境 1.启用或关闭window功能 2.设置万维网服务 3.点击确定等待配置更改 二.创建新的Web网站并进行设置 1.打开IIS管理 2.配置默认的网站 3.创建新的网站 4.测试 三.可能出现的问题 1.404错误 前一篇已经记录了如何创建项目并发布到文件夹&#x…

配置管理数据库(CMDB)

什么是CMDB 配置管理数据库(Configuration Management Database,简称CMDB)是组织IT基础结构中配置项(Configuration Item)及其关系的数据库。CI指示了任何需要管理的、以确保成功交付服务的项目。CI可以是一个具体的实体,如服务器、交换机,也…

软件测试的自动化工具

在软件开发过程中,测试是必不可少的一个环节。而在测试中,测试人员需要花费大量的时间和精力进行手动测试,这不仅费时费力,而且效率较低。因此,自动化测试工具的出现为测试人员提供了更加便捷高效的测试方法。本文将介…