Java:内部类

news2024/9/29 11:32:10

目录

  • 1.内部类介绍
  • 2.实例内部类
  • 3.静态内部类
  • 4.局部内部类
  • 5.匿名内部类

1.内部类介绍

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中,**可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。**内部类也是封装的一种体现。
注意事项
1.定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类,举例如下

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

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

class OuterClass{
    public int data1=1;
    private int data2=2;
    class InnerClass{
        public int data1=100;
        public int data3=3;

    }
}
public class Test {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        OuterClass.InnerClass innerClass=out.new InnerClass();
    }
}

编译后产生的字节码文件
在这里插入图片描述

2.实例内部类

代码形式

class OuterClass{
    public int data1=1;
    private int data2=2;
    class InnerClass{
        public int data1=100;
        public int data3=3;
    }
}

1.外部类中的任何成员都可以在实例内部类方法中直接访问

class OuterClass{
    public int data1=1;
    private int data2=2;
    public void test(){
        System.out.println("OuterClass::test()");
        System.out.println(data1);    
    }
    class InnerClass{
        public void test1(){
            System.out.println("InnerClass::test()");
            System.out.println(data1);
            System.out.println(data2);
            //直接调用外部类的data1和data2并打印
        }
    }
}
public class Test {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        OuterClass.InnerClass innerClass=out.new InnerClass();
        innerClass.test1();
    }
}

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

2.实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
在这里插入图片描述
使用private修饰后,下面实例化的时候就会报错,如下所示
在这里插入图片描述
被public修饰就不展示了
3.在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问

class OuterClass{
    public int data1=1;
    private int data2=2;
    public void test(){
        System.out.println("OuterClass::test()");
        System.out.println(data1);
    }
    class InnerClass{
        public int data1=100;//与外部类同名成员
        public void test1(){
            System.out.println("InnerClass::test()");
            System.out.println(this.data1);
            System.out.println(data2);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        OuterClass.InnerClass innerClass=out.new InnerClass();
        innerClass.test1();
    }
}

运行结果
在这里插入图片描述
如果要想访问到外部类的同名方法,修改如下

public void test1(){
            System.out.println("InnerClass::test()");
            System.out.println(OuterClass.this.data1);
            System.out.println(data2);
        }

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

4.实例内部类对象必须在先有外部类对象前提下才能创建
下面提供两种实例化方式

public static void main(String[] args) {
// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
        OuterClass out=new OuterClass();
        OuterClass.InnerClass innerClass=out.new InnerClass();
        OuterClass.InnerClass innerClass1=new OuterClass().new InnerClass();
    }

5.实例内部类的非静态方法中包含了一个指向外部类对象的引用

class OuterClass{
    public int data1=1;
    private int data2=2;
    public void test(){
        System.out.println("OuterClass::test()");
        System.out.println(data1);
    }
    class InnerClass{

        public void test1(){
            OuterClass out=new OuterClass();
  //在内部类方法中创建一个外部类对象,通过这个对象调用外部类成员方法
            out.test();
            System.out.println("=================");
            System.out.println("InnerClass::test()");
            System.out.println(data1);
            System.out.println(data2);
        }

    }
}
public class Test {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        OuterClass.InnerClass innerClass=out.new InnerClass();
        innerClass.test1();
    }
}

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

6.外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

class OuterClass{
    public int data1=1;
    private int data2=2;
    public void test(){
        OuterClass.InnerClass innerClass=new InnerClass();
        //在外部类中实例化了一个内部类对象调用内部类成员
        innerClass.test1();
        System.out.println("===================");
        System.out.println("OuterClass::test()");
        System.out.println(data1);
    }
    class InnerClass{
        public void test1(){
            System.out.println("InnerClass::test()");
            System.out.println(data1);
            System.out.println(data2);
        }

    }
}
public class Test {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        out.test();
    }
}

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

3.静态内部类

1.在静态内部类中只能访问外部类中的静态成员

class OuterClass{
    public int data1=1;
    private int data2=2;
    static int data3=3;
    public void test(){
        System.out.println("OuterClass::test()");
        System.out.println(data1);
    }
    static class InnerClass{
        public void test1(){
            System.out.println("InnerClass::test()");
            System.out.println(data1);//非静态成员,会报错
            System.out.println(data2);//非静态成员,会报错
            System.out.println(data3);//静态成员正常访问
        }
    }
}

在这里插入图片描述
如果确实想访问,我们该如何做?
在内部类方法里实例化一个外部类方法

static class InnerClass{
        public void test1(){
            OuterClass out=new OuterClass();
            System.out.println("InnerClass::test()");
            System.out.println(out.data1);
            System.out.println(out.data2);
            System.out.println(data3);
        }

运行结果
在这里插入图片描述
2.创建静态内部类对象时,不需要先创建外部类对象

public class Test {
    public static void main(String[] args) {
        OuterClass.InnerClass innerClass=new OuterClass.InnerClass();
        //直接通过外部类调用就可创建静态内部类的对象
        innerClass.test1();
    }
}

4.局部内部类

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

class OuterClass{
    public void method() {
        int data1=1;
        class InnerClass{
            void test1(){
                System.out.println("InnerClass::test1()");
                System.out.println(data1);
            }
        }
        //只能在方法体内部使用
        InnerClass innerClass=new InnerClass();
        innerClass.test1();
    }
}
public class Test {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        out.method();
    }
}

运行结果
在这里插入图片描述
如果在方法题外部使用会出现报错
在这里插入图片描述

2.不能被public、static等修饰符修饰
报错结果如下
在这里插入图片描述
在这里插入图片描述

3.编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
在这里插入图片描述
4.几乎不会使用

5.匿名内部类

匿名内部类可以用来实现一个接口并创建一个新的线程,举例如下

interface ITestable{
    void test();
}
public class Test {
    public static void main(String[] args) {
        new ITestable(){//直接实现这个接口
            @Override
            public void test() {
                System.out.println("hello zzuli");
            }
        };
    }
}

上面的代码相当于下面通过implments来实现一个接口

interface ITestable{
    void test();
}
class A implements ITestable{

    @Override
    public void test() {
        System.out.println("hello zzuli");
    }
}
public class Test {
    public static void main(String[] args) {
        A a=new A();
    }
    
}

我们通过匿名内部类来实现接口,那么我们应该怎么使用接口里的方法呢?
下面提供两种方法
方法一:直接通过.来调用,代码如下

interface ITestable{
    void test();
}
public class Test {
    public static void main(String[] args) {
        new ITestable(){
            @Override
            public void test() {
                System.out.println("hello zzuli");
            }
        }.test();//直接调用
    }
}

方法二:通过创建一个变量来调用(推荐使用)

interface ITestable{
    void test();
}
public class Test {
    public static void main(String[] args) {
        ITestable I=new ITestable(){
            @Override
            public void test() {
                System.out.println("hello zzuli");
            }
        };
        I.test();//通过变量名调用
    }
}

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

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

相关文章

处理游戏提示找不到steam_api64.dll丢失的方法

steam_api64.dll 是一个专门为 64 位 Windows 操作系统设计的动态链接库(Dynamic Link Library,简称 DLL)文件,与 steam_api.dll 类似,但针对的是 64 位应用程序。它属于 Steam 平台的一部分,主要服务于通过…

【Redis】面试题汇总

Redis什么是Redis、使用场景有哪些Redis 为什么这么快?Redis 数据类型及使用场景五种常见的 Redis 数据类型是怎么实现?Redis是单线程吗Redis 采用单线程为什么还这么快?Redis 如何实现数据不丢失?Redis 如何实现服务高可用&#…

为什么中级职称评审不通过?有什么原因?

参与过职称评审或者有了解过职称评审的小伙伴们,应该都知道,职称评审都是有通过率,不是你去评,一定会评下来,一定会发证的,那么评审为什么不通过?有哪些原因呢? 现在职称评审人越来越…

vue框架中的组件通信

vue框架中的组件通信 一.组件通信关系二.父子通信1.props 校验2.prop & data、单向数据流 二.非父子通信-event bus 事件总线三.非父子通信 (拓展) - provide & inject四.v-model简化父子通信代码五. .sync修饰符 一.组件通信关系 组件关系分类: 1.父子关系…

细水雾发生器你的相信我的诚信

做销售就是两个信:你的相信!我的诚信!成交就两颗心:你的放心!我的用心!你给我一次合作的机会,我给你十分满意的产品。一次合作,终身朋友~ 产品的结构: 细水雾…

快速了解什么是MES系统

近年来在制造业的推动下,大家是否会经常听到MES系统这一词,但是对于其具体能解决什么问题却不是很清晰。接下来,让大家快速地了解一下到底什么是MES系统以及MES系统能够解决什么问题。 什么是MES制造执行系统 制造执行系统(Manufa…

TBWeb开发版V3.2.6免授权无后门Chatgpt系统源码下载及详细安装教程

TBWeb系统是基于 NineAI 二开的可商业化 TB Web 应用(免授权,无后门,非盗版,已整合前后端,支持快速部署)。相比稳定版,开发版进度更快一些。前端改进:对话页UI重构,参考C…

Excel超级处理器,批量创建工作表,这也太方便了吧

在工作中,经常要创建或复制多个工作表,按照日期或指定的工作表名,为了能够更加方便快捷,那么下面介绍使用超级处理的应用。 超级处理器下载与安装 1、按照本月日期创建新工作表 2、按照本月日期复制工作表 3、按照单元格内容创建…

外显子测序wes

外显子是基因组中能够转录组出成熟RNA的部分。一个基因组中所有外显子的集合,即为外显子组。值得注意的是,通常所说的全外显子组测序,是指针对蛋白编码基因的外显子,很少涉及非编码基因。 基因(gene)是DNA中含有特定遗传信息的一…

AI智能电销机器人的营销策略是什么?

近年来,伴随着制造业新一轮的数字化智能化转型浪潮。各大企业开始使用电销机器人,解决了传统电销工作过程中的许多问题,更显著的是:电话机器人在替代人工工作基础上,节约人工成本70%以上,极大程度地高额完成…

从本地创建项目到 Gitee 提交的完整教程

1、本地创建一个新项目 2.进入想上传的项目的文件夹,然后右键点击git bash 3.初始化本地环境,把该项目变成可被git管理的仓库 4.添加该项目下的所有文件到暂存区 5.使用如下命令将文件添加到仓库中去 6.在gitee上创建以自己项目名称命名的空项目 7.将本地…

Windows上使用VSCode连接远程服务器(附图文过程)

1、下载VSCode 官网下载地址,选择需要的进行下载 2、安装SSH插件 安装完成之后,启动vscode,选择左侧Extensions 选项卡,在输入框搜索 remote ,选择安装Remote-SSH插件(我使用了汉化,如果要用…

ubuntu18.04与windows文件互传

目录 window下载Xftp软件ubuntu上的配置windows端Xftp软件的使用 window下载Xftp软件 下载:家庭/学校免费版 安装教程推荐下面的文章 xftp7免费版安装教程(详细) ubuntu上的配置 在进入系统后,确保有网络连接的情况下按Ctrl A…

制作适用于openstack平台的win10镜像

1. 安装准备 从MSDN下载windows 10的镜像虚拟机开启CPU虚拟化的功能。从Fedora 网站下载已签名的 VirtIO 驱动程序 ISO 。 创建15 GB 的 qcow2 镜像:qemu-img create -f qcow2 win10.qcow2 15G 安装必要的软件 yum install qemu-kvm qemu-img virt-manager libvir…

28map,set关联式容器

序列式容器 vector、list、deque(单纯的纯数据) 关联式容器 map、set,哈希,,,(数据之间有很强的关联性,不是单纯的为了存储数据) Set 底层是搜索树(红黑树) T是key ,compare是仿函数&#xff0…

书生·浦语大模型-第四节课笔记/作业

笔记 作业 xtuner train ./config/internlm2_chat_7b_qlora_alpaca_e3_copy.py --work-dir ./train微调前效果 微调后效果 微调过程-transformer-lora

Django中的定时任务与后台任务队列的实践

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在Web开发中,处理定时任务和后台任务队列是很常见的需求。Django作为一个功能强…

032——从GUI->Client->Server->driver实现ds18b20数据的采集

目录 1、客户端修改和通信帧确定 2、 修改服务器程序 3、 添加driver_handle程序 4、 测试 1、客户端修改和通信帧确定 上次写dht11的时候顺手把ds18b20的GUI一起改了所以这次直接去改client #ds18b20elif cmd[2] 0 and cmd[3] 6:if cmd[4] g:try:global_var.TEMcmd[5]…

在 Linux 上通过 udev 规则绑定 ttyUSB 设备的相对地址

文章目录 问题描述解决方案1. 分辨当前 USB 设备的绝对地址2. 使用绝对地址查看设备属性3. 使用 udev 规则绑定设备到相对地址3.1. 区分多个不同型号 USB 设备3.2. 区分多个相同型号 USB 设备 问题描述 Linux 系统开机时会随机为连接的 USB 设备随机分配 /dev/ttyUSB* 这样的绝…

ubuntu20 解决网线不能联网 RTL8111/8168/8411

这种问题一般是驱动没有正确安装。 ----RTL8111/8168/8411是一块比较坑的网卡。 1、 查看网卡信息 lspci |grep Ethernet2、 对于高版本的Ubuntu,能直接使用命令安装驱动。下面的r8168-dkms需根据网卡信息修改,上面的网卡信息还有8111,但逐个…