【JavaSE】类和对象(三)——内部类

news2024/9/29 5:31:33

目录

1. 何为内部类

2. 内部类的分类

    2.1 静态内部类

        2.1.1 如何实例化静态内部类的对象?

        2.1.2 外部类与静态内部类如何相互访问? 

    2.2 非静态内部类/实例内部类

        2.2.1  非静态内部类不能定义静态的成员变量以及方法

        2.2.2 非静态内部类的实例化 

        2.2.3 外部类与非静态内部类的互相访问

        2.2.4 当内外部类的成员变量名字相同时 

    2.3 局部内部类

    2.4 匿名内部类


1. 何为内部类

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,称为内部类。内部类也是封装的一种体现。

2. 内部类的分类

2.1 静态内部类

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

class OutClass {

     //静态内部类:

    static class InnerClass{

    }

}

2.1.1 如何实例化静态内部类的对象?

    public static void main(String[] args) {
        //实例化一个内部类对象;
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
    }

2.1.2 外部类与静态内部类如何相互访问? 

1. 静态内部类访问外部类成员:

class OuterClass{
    public int a = 1;
    private int b = 2;
    public static int c = 3;
    static class InnerClass {
        public int d = 4;
        private int e = 5;
        public static int f = 6;

        public void func(){
            System.out.println("static->InnerClass::func");
            System.out.println(a); //红字报错!!
            System.out.println(b); //红字报错!!
            System.out.println(c);
            System.out.println(d);
            System.out.println(e);
            System.out.println(f);
        }
    }
}

由前面学过的知识可知,所有 static 修饰的,都不依赖于对象,但如果没有 static 修饰,就一定得实例化对象之后才能访问。所以在静态内部类内部直接访问外部类的非静态成员是不行的,得实例化对象才行:

            //将上述代码注释处修改为:
            OuterClass outerClass = new OuterClass();
            System.out.println(outerClass.a);
            System.out.println(outerClass.b);

调用 func 方法:

    public static void main(String[] args) {
        //实例化一个内部类对象;
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
        innerClass.func();
    }

2. 外部类访问静态内部类成员:

在外部类中,写这样一个方法:

 发现,外部类方法直接访问内部类成员,全部红字报错,该如何修改?

    public void outerFunc(){
        System.out.println("OuterClass::outerFunc");
        InnerClass innerClass = new InnerClass();
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(innerClass.d); //d 为静态内部类非静态成员变量 
        System.out.println(innerClass.e); //e 为静态内部类非静态成员变量 
        System.out.println(InnerClass.f); //f 是静态内部类的静态成员变量,通过类名便可访问
    }

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

2.2 非静态内部类/实例内部类

public class OutClass {

    class InnerClass{

    }

}

// OutClass是外部类

// InnerClass是非静态内部类

2.2.1  非静态内部类不能定义静态的成员变量以及方法

 但如果非要有,加个 final :

 加了 final ,f 变成常量,而常量在程序编译过程中,是一个确定的值。

2.2.2 非静态内部类的实例化 

    public static void main(String[] args) {
        OuterClass1 outerClass = new OuterClass1();
        OuterClass1.InnerClass1 innerClass1 = outerClass.new InnerClass1();
        System.out.println(innerClass1.d);
    }

在此也可以看出,非静态内部类相较静态内部类麻烦, 需要实例化外部类的对象。一般情况下,使用静态内部类较多。

2.2.3 外部类与非静态内部类的互相访问

1. 非静态内部类访问外部类:

class OuterClass1{
    public int a = 1;
    private int b = 2;
    public static int c = 3;
    class InnerClass1{
        public int d = 4;
        private int e = 5;
        public static final int f = 6;
        public void func(){
            System.out.println("InnerClass1::func");
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
            System.out.println(d);
            System.out.println(e);
            System.out.println(f);
        }
    }
}

public class Text {
    public static void main(String[] args) {
        OuterClass1 outerClass = new OuterClass1();
        OuterClass1.InnerClass1 innerClass1 = outerClass.new InnerClass1();
        innerClass1.func();
    }
}

2. 外部类访问非静态内部类:

    public void func1(){
        System.out.println("OuterClass1::func1");
        InnerClass1 innerClass1 = new InnerClass1();
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(innerClass1.d);
        System.out.println(innerClass1.e);
        System.out.println(innerClass1.f);
    }

2.2.4 当内外部类的成员变量名字相同时 

class OuterClass2{
    public int a = 4;
    class InnerClass2{
        public int a = 444444;
        public void func(){
            System.out.println(a);
        }
    }
}

调用 func 时会输出 444444

那如果非要输出外部类的 a ,该如何?

System.out.println(OuterClass2.this.a);

在非静态外部类中,包含两个 this,一个是自己的 this ,一个是代表外部类对象的引用,像上面代码写的,OuterClass2.this.a

2.3 局部内部类

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

class OutClass3{
    public void func(){
            class InnerClass3{
                public int a = 8;
                public void fun(){
                    System.out.println("hello!");
                }
        }
        InnerClass3 innerClass3 = new InnerClass3();
            innerClass3.fun();
    }
}
public class Text {
    public static void main(String[] args) {
        OutClass3 outClass3 = new OutClass3();
        outClass3.func();
    }
}

【注意事项】

1. 局部内部类只能在所定义的方法体内部使用

2. 不能被public、static等修饰符修饰

3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class

4. 几乎不会使用

2.4 匿名内部类

接口是不能实例化的,需要借助一个具体类,如:

interface IA{
    void func();
}

class AA implements IA{
    public void func(){
        System.out.println("hehehe");
    }
}

public class Text {
    public static void main(String[] args) {
        IA ia = new AA();
        ia.func();
    }
}

而匿名内部类可以实现跟 class AA 一样的功能:

    public static void main(String[] args) {
        new IA(){
            @Override
            public void func() {
                System.out.println("呜呜呜~");
            }
        };
    }

匿名内部类也意味着,这是一个实现了 IA 这个接口,并且重写了 func 方法的类。

那如何调用呢?很简单:

    public static void main(String[] args) {
        new IA(){
            @Override
            public void func() {
                System.out.println("呜呜呜~");
            }
        }.func();
    }

此时的匿名内部类是没有字节码文件的。

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

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

相关文章

三层-生成树-ospf-速端口思科练习实验

♥️作者:小刘在这里 ♥️每天分享云计算网络运维课堂笔记,疫情之下,你我素未谋面,但你一定要平平安安,一 起努力,共赴美好人生! ♥️夕阳下,是最美的,绽放,…

Spark-SaprkStreaming(概述、架构、原理、DStream转换、案例)

文章目录SparkStreaming概述特点架构原理DStream和RDD的区别DAG如何读取数据(※)WordCount 案例实操代码解析RDD 队列用法及说明案例实操自定义数据源Kafka 数据源DStream 转换无状态转化操作Transformjoin有状态转化操作UpdateStateByKeyWindowOperationsDStream 输出优雅关闭…

pip命令安装torchnet包,超简单!

pip命令安装torchnet包,超简单! torchnet是torch的框架,它提供了一组抽象,旨在鼓励代码重用以及鼓励模块化编程。 目前,torchnet提供了四组重要的类: Dataset:以各种方式处理和预处理数据。 …

Typora入门教程

文章目录Typora入门教程1 简要介绍2 下载安装包3 常用操作3.1 标题3.2 加粗3.3 斜体3.4 高亮3.5 分割线3.6 图片3.7 链接3.8 引用3.9 列表3.10 目录3.11 表格3.12 代码块3.13 行内代码3.14 按键效果4 自定义快捷键5 Typora PicGo 阿里云OSS搭建个人笔记5.1 注意事项5.2 准备工…

Hibernate学习总结

文章目录一、图解运行过程二、核心代码三、session方法2、session缓存3、save()与persist()4、get()5、update()6、delete()7、evict()8、doWork(),可获得connection对象四、hibernate.cfg.xml(使用数据库连接池)五、*…

java项目-第176期ssm个人交友网站系统-java毕业设计

java项目-第176期ssm个人交友网站系统-java毕业设计 【源码请到下载专栏下载】 《个人交友网站》 该项目分为2个角色,管理员、用户角色。 用户可以浏览前台,包含功能有: 首页、交友信息、线下活动、系统公告、论坛信息 管理员进行后台登录,包…

【KNN分类】基于matlab模拟退火优化KNN、蝗虫算法优化KNN数据分类【含Matlab源码 2275期】

⛄一、1KNN算法思想 K近邻算法(KNN,K nearest neighbor algorithm)是机器学习中一种基本的分类与回归方法,其主要原理是通过对不同测试样本之间的距离进行量测,而后寻找最为相近的K个样本来进行分类,具有简单、直观、…

【LeetCode题目详解】(三)21.合并两个有序链表、141.环形链表、142.环形链表Ⅱ

目录 一、力扣第21题:合并两个有序链表 解法思路 代码一 代码二 代码三 二、力扣第141题:环形链表 1.快慢指针法 2.证明快慢指针是可行的 三、力扣第142题:环形链表Ⅱ 1.解题思路 2.代码 总结 一、力扣第21题:合并两个…

selenium自动化测试

文章目录1.什么是自动化测试2.UI自动化测试3, webdriver的原理元素的定位定位操作示例操作测试对象添加等待固定等待智能等待打印信息浏览器的操作浏览器最大化设置浏览器宽、高操作浏览器的前进、后退控制浏览器滚动条键盘事件键盘按键用法键盘组合键用法鼠标事件ActionChains…

接口测试(七)—— 参数化、数据库操作封装、接口自动化框架

目录 一、接口自动化测试框架 1、目录结构 二、封装iHRM登录 1、普通方式实现 2、登录接口对象层 3、登录接口测试用例层 4、封装断言方法 三、参数化 1、回顾UnitTest参数化 1.1 原始案例 1.2 参数化实现 1.3 从json文件读取 2、登录接口参数化 2.1 组织数据文…

ArcGIS:如何进行离散点数据插值分析(IDW)、栅格数据的重分类、栅格计算器的简单使用、缓冲区分析、掩膜?

目录 01 说明 02 实验目的及要求 03 实验设备及软件平台 04 实验内容与步骤 4.1 反距离权重插值分析 4.2 多栅格局域运算 4.3 按表格显示分区统计 4.4 重分类 4.5 邻域运算 4.6 矢量数据的裁剪 4.7 缓冲区分析及栅格数据提取分析 05 思考及讨论 01 说明 由于这次的作业是从word…

jsp+ssm计算机毕业设计宠物寻回系统【附源码】

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JSPSSM mybatis Maven等等组成,B/S模式 Mave…

2.两数相加

正在建设中 传送门: https://leetcode.cn/problems/add-two-numbers/ 题目描述 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。 请你将两个数相加,并以相同形…

git 进阶系列教程-------git使用流程

GIT使用流程 前言 初衷 git是一门很容易入门的项目管理工具,但是它是一门很难精通的技术。 git pull/git add ./git commit -m "message"/git push/......知道以上几个命令,或许再多一点,也许就能说:‘我会git’了。…

IDEA画UML类图

第一步(IDEA下载画图插件) PlantUML Integration 插件可以支持画图 第二步(创建类图文件) 点击之后会让选择 选择class即可 类图的语法 在画类图的时候分为五种 1. 依赖 依赖分为好多种, 作为成员变量,作为方法的入参和出参,在类中使用…

【JSP菜鸟教程】

简介 JSP是一种Java servlet&#xff0c;主要用于实现Java web应用程序的用户界面部分。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。 Scriptlet脚本小程序 如果你想在HTML中写Java代码&#xff0c;就需要将Java代码写入Scriptlet中&#xff0…

数据库实验一:数据定义与操作语言实验

实验一 数据定义与操作语言实验 实验 1.1 数据库定义实验 1.实验目的 理解和掌握数据库DDL语言&#xff0c;能够熟练地使用SQL DDL语句创建、修改和删除数据库、模式和基本表。 2.实验内容和要求 理解和掌握SQL DDL语句的语法&#xff0c;特别是各种参数的具体含义和使用方…

第十七届D2大会(I)

一、Web Compass-端内Web App解决方案揭秘 增强传统web端内方案&#xff0c;提供更好、更收敛的工程体验 二、自渲染跨端框架在字节跳动的实践与展望 基于Flutter Engine的二次开发 三、Qking&#xff1a;跨端JS引擎的深度探索与突破 常见js引擎&#xff0c;如&#xff1a;v8…

CSC7268

CSC7268概述: CSC7268是一款内置高压MOS的高性能、多工作模式的PWM控制芯片&#xff0c;内置多种保护机制。当系统为空载和轻载时&#xff0c;CSC7268采用Burst和Green控制模式可有效地减少了空载和轻载时的损耗。当系统为中载和重载时&#xff0c;芯片采用QR模式和CCM模式可有…

python基础: filter, lambda 函数表达式

filter(function or None, sequence)&#xff0c;其中sequence 可以是list ,tuple,string。这个函数的功能是过滤出sequence 中所有以元素自身作为参数调用function时返回True或bool(返回值)为True的元素并以列表返回. filter只能接受两个参(function,sequence) &#xff0c;其…