Java四大内部类之局部内部类、匿名内部类

目录

一、局部内部类

二、匿名内部类

基于接口的匿名内部类

基于类的匿名内部类

三、匿名内部类的实践


类的五大成员:属性、方法、构造器、代码块、内部类

内部类的分类

定义在外部类局部位置上(比如说方法内):
  • 局部内部类(有类名)
  • 匿名内部类(没有类名)
定义在外部类的成员位置上:
  • 成员内部类(没用static修饰)
  • 静态内部类(使用static修饰)

一、局部内部类

说明:局部内部类是定义在外部类的局部位置,比如方法种,并且有类名
  1. 可以直接访问外部类的所有成员,包含私有的
  2. 不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final
  3. 作用域:仅仅在定义它的方法或代码块中。
  4. 局部内部类---访问----》外部类的成员 【访问方式:直接访问】
  5. 外部类---访问---》局部内部类的成员
    1. 访问方式:创建对象,再访问(注意:必须再作用域内)
package com.hspedu.innerclass;
/*** 演示局部内部类的使用*/
public class LocalInnerClass {public static void main(String[] args) {//演示一遍Outer02 outer02 = new Outer02();outer02.m1();}
}class Outer02 {//外部类private int n1 = 100;private void m2() {System.out.println("Outer02 m2()");}//私有方法public void m1() {//方法//1.局部内部类是定义在外部类的局部位置,通常在方法//3.不能添加访问修饰符,但是可以使用final修饰//4.作用域:仅仅在定义它的方法或代码块中class Inner02 {//局部内部类(本质仍然是一个类)//2.可以直接访问外部类的所有成员,包含私有的public void f1() {//5.局部内部类可以直接访问外部类的成员,比如下面 外部类n1 和 m2()System.out.println("n1=" + n1);m2();}}//6.外部类在方法中,可以创建Inner02对象,然后调用方法即可Inner02 inner02 = new Inner02();inner02.f1();}}

输出结果

  1. 外部其他类---》不能访问---》局部内部类(因为 局部内部类地位是一个局部变量)
  2. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

Outer02.this 本质就是外部类的对象,即哪个对象调用了m1,Outer02.this就是哪个对象

输出结果:

二、匿名内部类

本质是类 内部类 该类没有名字 同时还是一个对象

说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名

匿名内部类的基本语法

new类或接口(参数列表){

        类体

};

基于接口的匿名内部类

未使用匿名内部类简化开发之前

package com.hspedu.innerclass;/*** 演示匿名内部类的使用*/
public class AnonymousInnerClass {public static void main(String[] args) {Outer04 outer04 = new Outer04();outer04.method();}
}class Outer04 {//外部类private int n1 = 10;//属性public void method() {//方法//基于接口的匿名内部类//1.需求:想使用IA接口,并创建对象//2.传统方式,是写一个类,实现该接口,并创建对象//3.需求是 Tiger/Dog 类只是使用一次,后面不使用//4.可以使用匿名内部类来简化开发IA tiger = new Tiger();tiger.cry();}
}interface IA {//接口public void cry();
}
class Tiger implements IA {@Overridepublic void cry() {System.out.println("老虎叫-----");}
}class Dog implements IA {@Overridepublic void cry() {System.out.println("小狗叫-----");}
}
class Father {//类public Father(String name) {//构造器}public void test() {//方法}
}

使用匿名内部类简化开发之后

package com.hspedu.innerclass;/*** 演示匿名内部类的使用*/
public class AnonymousInnerClass {public static void main(String[] args) {Outer04 outer04 = new Outer04();outer04.method();}
}class Outer04 {//外部类private int n1 = 10;//属性public void method() {//方法//基于接口的匿名内部类//1.需求:想使用IA接口,并创建对象//2.传统方式,是写一个类,实现该接口,并创建对象//3.需求是 Tiger/Dog 类只是使用一次,后面不使用//4.可以使用匿名内部类来简化开发//5.tiger的编译类型 ? IA//6.tiger的运行类型 ? 就是匿名内部类 XXXX => Outer04$1/*我们看底层 会分配 类名 Outer04$1class XXXX implements IA {@Overridepublic void cry() {System.out.println("老虎叫----");}};*///7.jdk 底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1实例,并且把地址//  返回给 tiger//8.匿名内部类使用一次,就不能再使用IA tiger = new IA(){@Overridepublic void cry() {System.out.println("老虎叫----");}};tiger.cry();System.out.println("tiger的运行类型:" + tiger.getClass());//        IA tiger = new Tiger();
//        tiger.cry();}
}interface IA {//接口public void cry();
}
//class Tiger implements IA {
//
//    @Override
//    public void cry() {
//        System.out.println("老虎叫-----");
//    }
//}
//
//class Dog implements IA {
//
//    @Override
//    public void cry() {
//        System.out.println("小狗叫-----");
//    }
//}
class Father {//类public Father(String name) {//构造器}public void test() {//方法}
}

要注意这段代码并不是直接创建接口的实例,而是创建了一个实现类该接口的类的实例

这个类的类名由jdk分配

匿名内部类的代码:

    IA tiger = new IA(){@Overridepublic void cry() {System.out.println("老虎叫----");}};

实际上等价于下面的代码

// 显式定义一个类实现接口
class Outer04$1 implements IA {@Overridepublic void cry() {System.out.println("老虎叫----");}
}// 在主方法中创建 MyPrinter 的对象
IA tiger = new Outer04$1();

基于类的匿名内部类

class Father {//类public Father(String name) {//构造器}public void test() {//方法}
}
    //演示基于类的匿名内部类//分析//1.father编译类型 Father//2.father运行类型 Outer04$2//3.底层会创建匿名内部类/*class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}}*///4.同时也直接返回了 匿名内部类 Outer04$2//注意("jack") 参数列表会传递给构造器Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}};System.out.println("father对象的运行类型=" + father.getClass());//Outer04$2father.test();

Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}};

等价于

    class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}}Father father = new Outer04$2("jack");

基于类的匿名内部类的第二种方式,这里我调用的是Person类

//直接调用,匿名内部类本身也是返回对象
//class 匿名内部类 extends Person {}
new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了 hi方法,zzzzzz");}
}.hi();
package com.hspedu.innerclass;public class AnonymousInnerClassDetail {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();//外部其他类---不能访问----》匿名内部类System.out.println("main hashcode=" + outer05);}
}class Outer05 {private int n1 = 99;public void f1() {//创建一个基于类的匿名内部类//不能添加访问修饰符,因为它的地位就是一个局部变量//作用域:仅仅在定义它的方法或代码块中Person p = new Person(){private int n1 = 88;@Overridepublic void hi() {//可以直接访问外部类的所有成员,包含私有的//如果外部类和匿名内部类的成员重名时,匿名内部类访问的话//默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员) 去访问System.out.println("匿名内部类重写了 hi方法 n1=" + n1 + "  外部内的n1=" + Outer05.this.n1);//Outer05.this 就是调用 f1的 对象System.out.println("Outer05.this hashcode=" + Outer05.this);}};p.hi();//动态绑定,运行类型是Outer05$1//        //也可以直接调用,匿名内部类本身也是返回对象
//        //class 匿名内部类 extends Person {}
//        new Person(){
//            @Override
//            public void hi() {
//                System.out.println("匿名内部类重写了 hi方法,zzzzzz");
//            }
//
//            @Override
//            public void ok(String str) {
//                super.ok(str);
//            }
//        }.ok("jack");}
}class Person {//类public void hi(){System.out.println("Person hi()");}public void ok(String str){System.out.println("Person ok()" + str);}
}
//抽象类/接口。。。

三、匿名内部类的实践

示例1

匿名内部类方式

public class InnerClassExercise01 {public static void main(String[] args) {//当作实参直接传递,简洁高效f1(new IL() {@Overridepublic void show() {System.out.println("这是一幅画。。。");}}); }//静态方法,形参是接口类型public static void f1(IL il){il.show();}
}
//接口
interface IL {void show();
}

传统方式

public class InnerClassExercise01 {public static void main(String[] args) {//传统写法f1(new Picture());}//静态方法,形参是接口类型public static void f1(IL il){il.show();}
}
//接口
interface IL {void show();
}//类->实现IL =》编程领域(硬编码)
class Picture implements IL {@Overridepublic void show() {System.out.println("这是一幅名画。。。。");}
}

示例2

package com.hspedu.innerclass;public class InnerClassExercise02 {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();cellPhone.alarmClock(new Bell() {//匿名内部类@Overridepublic void ring() {System.out.println("懒猪起床了");}});}
}interface Bell{//接口void ring();//方法
}class CellPhone{//类public void alarmClock(Bell bell){//形参是Bell接口类型bell.ring();//动态绑定}
}

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

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

相关文章

请求go web后端接口 java安卓端播放视频

前端代码 添加gradle依赖 implementation com.squareup.retrofit2:retrofit:2.9.0 implementation com.squareup.retrofit2:converter-gson:2.9.0 添加访问网络权限 <uses-permission android:name"android.permission.INTERNET" />允许http 请求请求 andro…

ARMS 用户体验监控正式发布原生鸿蒙应用 SDK

作者&#xff1a;羿莉 背景 对企业数据进行敏感数据扫描和保护可以提升企业或组织的数据安全。一方面敏感数据可能包括个人身份信息、财务记录、医疗记录等&#xff0c;定期扫描这些数据可以防止未经授权的访问和泄露。 另一方面&#xff0c;许多国家和地区都有关于数据保护的…

CSS学习记录14

CSS不透明度 opacity属性指定元素的不透明度/透明度。opacity属性的取值范围为0.0 ~ 1.0。 值越低&#xff0c;越透明&#xff1a; img {opacity: 0.5; } opacity属性通常与:hover选择器一同使用&#xff0c;这样就可以在鼠标悬停时更改不透明度&#xff1a; img {opacity: 0…

【YashanDB知识库】如何处理yasql输入交互模式下单行字符总量超过限制4000字节

现象 在yasql执行sql语句后报错&#xff1a;YASQL-00021 input line overflow (>4000 byte at line 4) 原因 yasql在交互模式模式下单行字符总量限制4000字节&#xff0c;超出该限制即报错。 交互式模式下&#xff0c;yasql会显示一个提示符&#xff0c;通常是 SQL>…

为何ZLG致远电子要推出LGA嵌入式核心板?

LGA嵌入式核心板究竟有什么好&#xff1f;能让ZLG致远电子陆续推出了5个系列12个型号的LGA嵌入式核心板。 到目前为止&#xff0c;ZLG致远电子一共推出了M1106/M1107、M1126、M6Y2C、 A6Y2C、MR6450等5个系列&#xff0c;共12个型号的LGA形态的嵌入式核心板&#xff0c;涵盖了A…

开源实时多模态AI Agent,搭载Gemini多模态API(在线体验)

今天发现一个惊艳的开源项目&#xff0c;利用多模态大模型API进行多智能体交互。支持RAG、搜索等。 TEN Agent 是一款由 TEN 提供支持的对​​话式 AI&#xff0c;集成了 Gemini 2.0 Multimodal Live API、OpenAI Realtime API、RTC 等。它提供实时的看、听和说功能&#xff0…

C++小白实习日记——Pollnet,Efvi,UDP,数据类型转换(下)

内容太多了&#xff0c;这篇记录UDP接收端 一&#xff0c;UDP接收端接收数据 有了pollnet这个开源项目的支持&#xff0c;接收端的步骤为&#xff1a;1&#xff09;初始化硬编码的参数&#xff1a;接口&#xff0c;IP和端口 2&#xff09;创建接收文件.csv 3&#xff09;读…

【ROS2】坐标TF入门

1、简介 1)定义: TF(TransForm)是用于坐标系管理的工具,它提供了快速、高效的坐标变换和时间同步功能。 2)坐标系 坐标系:在机器人系统中,存在多个坐标系,如基坐标系(Base Frame)、世界坐标系(World Frame)、工具坐标系、工件坐标系等。这些坐标系之间的关系在机…

[创业之路-197]:华为的成立发展与新中国的建立与发展路径的相似性比较

目录 一、公司比较 1、创业初期的艰难与挑战 2、坚持自主创新与研发 3、市场拓展与国际化战略 4、企业文化与社会责任 5、面临的挑战与应对策略 二、任正非管理企业的思想大量借鉴了毛泽东建国的思想 1、矛盾论与企业管理 2、群众路线与企业文化 3、战略思维与长远发…

Loadsh源码分析-filter,find,findLast,reject,partition

lodash源码研读之filter,find,findLast,reject,partition 一、源码地址 GitHub 地址: GitHub - lodash/lodash: A modern JavaScript utility library delivering modularity, performance, & extras.官方文档地址: Lodash 官方文档 二、结构分析 结构框图省略。 三、函…

全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之字符类型

要进行计算机程序设计&#xff0c;不仅仅进行科学数值类型计算&#xff0c;还需要处理一些文本信息&#xff0c;这就需要字符类型。在C中字符可以表示字母、符号等&#xff0c;在编程的时候&#xff0c;通常使用一对单引号括起来&#xff0c;例如&#xff1a;A,a,B,b,0等。字符…

Spring Boot 2.1.7 数据源自动加载过程详解

在 Spring Boot 中&#xff0c;数据源的自动配置是框架中一个关键功能&#xff0c;本文将以 Spring Boot 2.1.7 版本为例&#xff0c;详细讲解在单数据源情况下数据源是如何自动加载的。我们通过源码分析&#xff0c;追踪整个加载流程。 1. 自动配置类的发现 Spring Boot 使用…

Node.js第三方模块

1.npm 简介 npm:node package manager 是一个nodejs的包管理和开发工具。 2.npm作用 (提供第三方的安装模块) 1. 从npm服务器下载别人写的第三方js库包到本地使用。 2. 从npm服务器下载并安装第三方命令行程序到本地使用。 3. 将自己写的包或命令行程序上传到n…

剑指Offer 03比特位计数

只是记录 题目链接 题目链接 自己想出来的 第一种解法 思路简述 遍历[0,n]之间的数字&#xff0c;对于每一个数字按照二进制的方式展开&#xff0c;判断最低位置是否为1&#xff0c;若为1则1&#xff0c;反之不加&#xff0c;直到该数字等于0就停止。 public static int[] …

C# 23种设计模式(4)访问者模式(Visitor Pattern)

一、访问者模式介绍 访问者模式&#xff08;Visitor Pattern&#xff09;是一种行为设计模式&#xff0c;它允许你以一种新的方式来增加作用于一组对象的操作&#xff0c;而无需修改这些对象类的代码。访问者模式将数据操作与数据结构分离&#xff0c;适用于数据结构相对稳定但…

MySQL 锁机制详解

1 引言 在数据库系统中&#xff0c;锁是确保数据一致性和完整性的关键机制之一。MySQL提供了多种类型的锁来支持不同场景下的并发控制需求。本文将详细介绍MySQL中的主要锁类型&#xff0c;包括行级锁、表级锁、意向锁等&#xff0c;并探讨它们的工作原理及应用场景。 2 锁的基…

某j 全局控制输入框不能输入表情符

在FormItem.vue文件中的function handleRules()添加两处表情正则校验&#xff0c;代码如下 效果&#xff1a; function handleRules(): ValidationRule[] {const { rules: defRules [], component, rulesMessageJoinLabel, label, dynamicRules, required } props.schema;if…

java中File类

1、介绍 File类定义了一些与平台无关的方法来操作文件&#xff0c;可以通过调用File类中的方法&#xff0c;实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息&#xff0c;如文件所在的目录、文件长度、文件读写权限等。数据流可以将数据写入到文…

Linux高性能服务器编程 | 读书笔记 | 10. 高性能I/O框架库Libevent

10. 高性能I/O框架库Libevent Linux服务器程序必须处理三类事件&#xff08;I/O、信号和定时事件&#xff09;&#xff0c;在处理这三类事件时需要考虑以下问题&#xff1a; **统一事件源。**统一处理这三类事件既能使代码简单易懂&#xff0c;又能避免一些潜在的逻辑错误。实…

Javaweb web后端maven介绍作用安装

自动导入到这个项目 src是源代码 main主程序&#xff0c;核心代码 java是Java源代码 resources是项目配置文件 test测试相关的 maven概述 介绍 依赖在本地仓库查找&#xff0c;如果本地仓库有&#xff0c;用本地仓库的依赖&#xff0c;本地没有&#xff0c;连接中央仓库&…