【JavaSE】内部类

目录

前言

内部类

内部类的种类

1. 实例内部类

2 静态内部类

3 匿名内部类

4 局部内部类

结语


前言

内部类是我们前面学习遗留下来的知识点,在学完接口后才能更好的理解它,因此等到现在才讲

内部类

在Java中,我们可以将A类定义在B类或者一个方法的内部,这时A类就叫做内部类,B类就叫做外部类。内部类其实也是封装的一种体现。

class B {//...class A {//...}
}

内部类和外部类是共用一个Java源文件的,但是在编译后,内部类会形成单独的字节码文件(文件名为:外部类类名$内部类类名.class)


内部类的种类

  1. 实例内部类:非static修饰的成员内部类
  2. 静态内部类:static修饰的成员内部类
  3. 匿名内部类:与接口相关的内部类
  4. 局部内部类:定义在外部类的方法或{ }中

相比较于其他三种内部类,局部内部类用的很少,下面我们来一一认识这些内部类


1. 实例内部类

定义在类里面,方法外面,且不被static修饰。在实例内部类中,我们也可以正常定义成员变量和成员方法,静态的也可以

class OuterClass {public int O1;private int O2;public static int O3;/*** 实例内部类:定义在类里面,方法外面*/class InnerClass {public int I1;private int I2;public static int I3;public void testI() {System.out.println("InnerClass::testI()");}}public void testO() {System.out.println("OuterClass::testO()");}
}

接着我们来实例化内部类对象,它的语法格式如下:

方法一:外部类类名.内部类类名 变量名 = new 外部类类名( ).new 内部类类名( )

方法二:先 外部类类名.变量名1 = new 外部类类名( );

              再 外部类类名.内部类类名 变量名2 = 变量名1.new 内部类类名( )

public class Test {public static void main(String[] args) {//方法一:OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();//方法二:OuterClass outerClass = new OuterClass();OuterClass.InnerClass innerClass1 = outerClass.new InnerClass();}
}

总而言之,我们必须得通过外部类对象的引用再. new一个内部类对象


  • 创建好内部类对象后,我们就可以使用它来调用各种成员
        System.out.println(innerClass.I1);//调用内部类的成员innerClass.testI();//调用内部类的方法
  • 其实我们也可以在内部类方法中直接调用外部类的任何成员
        public void testI() {System.out.println("InnerClass::testI()");System.out.println(I1);System.out.println(O1);}
  •  当内部类和外部类存在同名成员变量时,内部类方法中调用时会优先访问内部类的成员,
     那如果我们想要精准的访问(同名)内部类成员和(同名)外部类成员要怎么做呢
     答案就是:this.同名变量 和 外部类名.this.同名变量
class OuterClass {public int same = 100;class InnerClass {public int same = 10;public void testI() {System.out.println("内部类"+this.same);System.out.println("外部类"+OuterClass.this.same);}}
}
public class Test {public static void main(String[] args) {OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();innerClass.testI();}
}

运行结果如下

或者我们也可以在内部类中创建一个外部类的对象,再用外部类的对象去调用外部类的成员

  • 外部类中,不能直接访问内部类中的成员,如果像访问就必须得先创建内部类的成员

2 静态内部类

定义在类里面,方法外面,且被static修饰。在静态内部类中,我们也可以正常定义成员变量和成员方法,静态的也可以

class OuterClass {public int O1;private int O2;public static int O3;/*** 静态内部类:定义在类里面,方法外面,且有static修饰*/static class InnerClass {public int I1;private int I2;public static int I3;public void testI() {System.out.println("InnerClass::testI()");}}public void testO() {System.out.println("OuterClass::testO()");}
}

 接着我们来实例化内部类对象,它的语法格式如下:

外部类类名.内部类类名 变量名 = new 外部类类名.内部类类名( )

(创建静态内部类对象时,不需要先创建外部类对象)

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

其他的东西跟实例内部类非常相似,但是在静态内部类中调用外部类非静态成员变量时,我们需要先创建外部类对象,用该对象才能引用

class OuterClass {public int O1;static class InnerClass {public int I1;public void testI() {OuterClass outerClass = new OuterClass();System.out.println(outerClass.O1);}}
}
public class Test {public static void main(String[] args) {OuterClass.InnerClass innerClass = new OuterClass.InnerClass();}
}

3 匿名内部类

在将匿名内部类前,我们先来看一下什么叫做匿名对象

//方法1:OuterClass outerClass = new OuterClass();outerClass.testO();System.out.println(outerClass.O1);
//方法2:new OuterClass().testO();System.out.println(new OuterClass().O1);

在方法1中,我们使用OuterClass引用创建了一个outerClass对象,打印O1和调用testO( )方法

在方法2中,我们使用new OuterClass( )直接打印O1和调用testO( )方法

方法2中每次都会创建一个新的对象,它没有用变量去承接对象的地址,此时这个对象就叫做匿名对象


匿名内部类跟接口有关,我们都知道,接口不能直接创建对象。我们通常会用一个类去实现接口,重写方法,这样才能实例化类的对象,从而使用接口。而匿名内部类就这个过程有点相似

interface ITest {void test();
}public class Test {public static void main(String[] args) {new ITest() {@Overridepublic void test() {System.out.println("重写后的test()");}};}
}

其中,这部分就叫做匿名内部类

它并没有真正实例化接口对象;它等同于一个类实现了这个接口,同时重写了test方法,但是这个类我们并不知道它叫什么,这就是匿名内部类


那如果我们想要调用test方法,要怎么做呢?

方法一:可以直接在匿名内部类后面. test( )

        new ITest() {@Overridepublic void test() {System.out.println("重写后的test()");}}.test();

 

方法二:创建一个匿名内部类对象,再用对象去调用test方法

        ITest iTest = new ITest() {@Overridepublic void test() {System.out.println("重写后的test()");}};iTest.test();

 


4 局部内部类

定义在方法里的类,即为局部的局部,只能在当前方法里使用,出了方法后就没用了,局限性很大

class OuterClass {public int O1;public void testO() {class InnerClass {public int I1;public void testI() {System.out.println("InnerClass::testI()");}}}
}

它不能被public、static修饰;它也有自己独立的字节码文件,格式为:外部类类名$数字+内部类类名.class

因为局限性太大,我们几乎不会使用它,了解即可 

结语

关于内部类我们就讲到这里。希望大家能喜欢这篇文章,有总结不到位的地方还请多多谅解,若有出现纰漏,希望大佬们看到错误之后能够在私信或评论区指正,博主会及时改正,共同进步!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能(pytorch)搭建模型25-基于pytorch搭建FPN特征金字塔网络的应用场景,模型结构介绍

大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型25-基于pytorch搭建FPN特征金字塔网络的应用场景,模型结构介绍。特征金字塔网络(FPN)是一种深度学习模型结构,主要应用于目标检测任务中&am…

什么是 SSL 证书?

SSL 证书的介绍 SSL(Secure Sockets Layer)证书是一种由数字证书颁发机构(CA)签发的加密证书,用于在 Web 浏览器和服务器之间建立安全连接。SSL 证书能够确保网站和应用程序的数据传输过程中不被窃听、篡改或伪造&…

从0配置React

在本地安装和配置React项目,您可以使用create-react-app这个官方推荐的脚手架工具。以下是安装React的步骤,包括安装Node.js、使用create-react-app创建React应用,以及启动开发服务器。 下载安装node.js运行以下命令,验证Node.js…

系列学习前端之第 7 章:一文掌握 AJAX

1、AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML(中文名:阿贾克斯),就是异步的 JS 和 XML。AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。AJAX 可以在浏览器中向服务器发送异步请求…

Wasm初上手

总之也是为了扩宽技术面吧。。。我也不知道为什么就想试试了,就酱。 参考阅读:极客时间《WebAssembly入门课》 安装wasm的编译器Emscripten。Emscripten 是一个“源到源”语言编译器工具集,这个工具集可以将 C/C 代码编译成对应 JavaScript 代…

AI学习-Pandas数据处理分析

文章目录 1. Pandas概述2. Series用法2.1 Series的创建2.2 Series的取值2.3 Series的相关方法 3. DataFrame用法3.1 DataFrame创建3.2 DataFrame取值3.3 DataFrame相关方法 1. Pandas概述 ​ Pandas 是一个开源的数据分析处理库,它应用在数据科学、统计分析、机器学…

手机短信验证码自动转发到服务器

今天写一个自动化处理程序,需要验证码登录,怎么样把手机收到的短信自动转发到服务器接口呢? 利用ios手机快捷指令的功能 打开快捷指令点击中间自动化点击右上角号选择信息信息包含选取,输入验证码选择立即执行点击下一步按下图配…

程序汪接的4万智慧餐饮项目

本文章来自程序汪背后的私活小团队,开发智慧餐厅的小程序 由于程序汪太忙于是把这个项目让一个靠谱粉丝开发了,当然开发质量和进度我会跟踪,具体分析如下 B站【我是程序汪】 老程序员接了一个4万的智慧餐饮项目,开发周期60天 小程…

Docker中常见的命令行

1 docker的全部命令 docker attach #连接到正在运行中的容器 docker build #使用 Dockerfile 创建镜像 docker builder #管理builds docker builder prune #清除build缓存 docker checkpoint #管理checkpoints docker checkpoint create #从正在运行的容器创建检…

LATTICE进阶篇DDR2--(2)详解IPUG35---基于官方例程

前言 本章主要讲述根据《DDR & DDR2 SDRAM Controller IP Cores User’s Guide 》数据手册,配合ddr2的demo仿真,学习DDR2的IP核时序控制。 器件:Lattice ECP3 环境:Win10 Diamond3.13 ModelSim SE-64 10.5 一、下载DDR2…

【链表专题】(2. 两数相加 23. 合并 K 个升序链表 25. K 个一组翻转链表)

文章目录 2. 两数相加23. 合并 K 个升序链表25. K 个一组翻转链表 2. 两数相加 题目链接: leetcode2. 两数相加 class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode cur1 l1,cur2 l2;ListNode newHead new ListNode(0);ListNode prev ne…

STM32的简介

内存 一般MCU包含的存储空间有FLASH和RAM,(RAM和flash又有片上和片外的区别,片上表示mcu自带的,已经封装在MCU内部的,片外表示外挂的,当项目中需要做一些复杂的应用,会存在资源不足的情况,这时…

MIT最新研究成果 机器人能够从错误中纠偏 无需编程介入和重复演示

目前科学家们正在努力让机器人变得更加智能,教会他们完成诸如擦拭桌面,端盘子等复杂技能。以往机器人要在非结构化环境执行这样的任务,需要依靠固定编程进行,缺乏场景通用性,而现在机器人的学习过程主要在于模仿&#…

LeetCode 双指针专题

11.盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不…

数据结构——lesson13排序之计数排序

💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…

基于单片机锂电池电量检测数码管显示系统设计

**单片机设计介绍,基于单片机锂电池电量检测数码管显示系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机锂电池电量检测数码管显示系统设计的主要目标是实时、准确地检测锂电池的电量,并…

【python】常用函数汇总(持续更新……)

文章目录 【numpy.exp()】返回e的幂次方,e是一个常数为2.71828【np.dot()】矩阵相乘【np.linalg.inv()】矩阵求逆 【numpy.exp()】返回e的幂次方,e是一个常数为2.71828 举例:numpy.exp() 【np.dot()】矩阵相乘 【要点】 1、前者的列数后者…

浅谈Spring体系的理解

浅谈Spring知识体系 Spring Framework架构图Spring家族技术生态全景图XMind汇总 本文不涉及细节,主要回答两个问题: Spring家族技术生态全景图有哪些Spring Framework架构下每个模块有哪些东西,以及部分模块之间的关联关系 Spring Framework架…

iOS - Runtime - Class的结构

文章目录 iOS - Runtime - Class的结构前言1. Class的结构1.1 Class的结构1.1.1 objc_class1.1.2 class_rw_t1.1.3 class_ro_t 1.2 class_rw_t和class_ro_t的区别1.3 class_rw_t和class_ro_t的关系1.3.1 分析关系1.3.2 原因 1.4 method_t1.4.1 Type Encoding1.4.2 types说明1.4…

AJAX-项目优化(目录、基地址、token、请求拦截器)

目录管理 基地址存储 在utils/request.js配置axios请求基地址 作用&#xff1a;提取公共前缀地址&#xff0c;配置后axios请求时都会baseURLurl 填写API的公共前缀后&#xff0c;将js文件导入到html文件中 <script src"../../utils/request.js"></script&…