当前位置: 首页 > news >正文

Java的匿名内部类(重要)

说明:

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

解读:

(1)匿名内部类的本质是类        (2)它是一个内部类        (3)该类没有名字      (4)它同时还是一个对象

1.匿名内部类的基本语法:

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

        类体

};

引出:

package com.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类只使用一次,以后再也不使用了//4.解决方案:使用匿名内部类简化开发Tiger tiger = new Tiger();tiger.cry();}
}
interface IA{        //接口public void cry();
}
class Father{public Father(String name) {    //构造器}public void test(){     //方法}
}
class Tiger implements IA{@Overridepublic void cry() {System.out.println("老虎叫.....");}
}

基于接口的匿名内部类的使用:

package com.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类只使用一次,以后再也不使用了//4.解决方案:使用匿名内部类简化开发//5.tiger的编译类型是IA//6.tiger的运行类型就是匿名内部类//如果Father是抽象类,则必须实现抽象类中的方法/*此时的匿名内部类 看底层:class Outer04$1 implements IA{        //匿名内部类的名称 = 外部类名称 + $1,也就是Outer04$1@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());}
}
interface IA{        //接口public void cry();
}
class Father{public Father(String name) {    //构造器}public void test(){     //方法}
}

基于类的匿名内部类的使用:
 

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

我的理解:

        就是先创建一个子类对象,然后jvm创建一个匿名内部类,将这个匿名内部类的匿名对象赋给最先创建的子类对象,而这个匿名内部类的创建过程只有一次,子类对象可以无数次使用

匿名内部类的使用:

        匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出这个特点,因此可以调用匿名内部类方法有下面两种:

package com.innerclass;public class AnonymousInnerClassDetail {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();}
}
class Outer05{private int n1 = 99;public void f1(){//创建一个基于类的匿名内部类//调用方式第一种:Person来接收Person person = new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了hi()");}};person.hi();//动态绑定,它的编译类型是Person,运行类型是Outer05$1//调用方式第二种:创建匿名对象直接调用//匿名内部类本身也是返回对象new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了hi()...................");}@Overridepublic 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.可以直接访问外部类的所有成员,包括私有的

2.不能添加访问修饰符,因为它的低位就是一个局部变量

3.作用域:仅仅在定义它的方法或代码中

4.匿名内部类---访问--->外部类成员[访问方式:直接访问]

5.外部其他类--不能访问-->匿名内部类(因为 匿名内部类地位是一个局部变量)

6.如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

匿名内部类的最佳实践:

当作实参直接传递,简洁高效

package com.innerclass;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{public void show();
}

练习

package com.innerclass;public class InnerClassExercise02 {public static void main(String[] args) {Cellphone cellphone = new Cellphone();cellphone.alarmClock(new Bell(){@Overridepublic void ring() {System.out.println("懒猪起床了");}});cellphone.alarmClock(new Bell() {@Overridepublic void ring() {System.out.println("小伙伴们上课了");}});}
}
//有一个铃声接口Bell,里面有个ring方法.
//有一个手机类Cellphone,具有闹钟功能 alarmClock 参数是Bell类型
//测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起来了
//再传入另一个匿名内部类(对象),打印:小伙伴上课了
interface Bell{void ring();
}
class Cellphone{public void alarmClock(Bell bell){  //形参是接口类型bell.ring();}
}
http://www.dtcms.com/a/523930.html

相关文章:

  • 基于PCA算法降维设备多维度传感器数据
  • java基础-方法
  • 51单片机基础-DS18B20温度传感器
  • 时空的几何化:论黑洞视界下光速的绝对不变性与表观变异
  • Uni-App(Vue3 + TypeScript)项目结构详解 ------ 以 Lighting-UniApp 为例,提供源代码
  • 如何帮网站广州广告推广公司
  • EPLAN电气设计常见报错与解决方案(一)
  • Unity TextMeshPro 输入表情
  • php简易企业网站源码nodejs网站开发
  • 《打破数据孤岛:3D手游角色表情骨骼协同的实践指南》
  • 【数据结构】数据结构核心考点:AVL树删除操作详解(附平衡旋转实例)
  • 当“Make”坏了,我们该如何“Make”
  • 【北京迅为】iTOP-4412精英版使用手册-第六十七章 USB鼠标驱动详解
  • 基于Three.js在Vue中实现3D模型交互与可视化
  • 网站功能分析门户网站建设招标公告
  • 【计算机网络】HTTP协议(二)——超文本传输协议
  • ip开源网站FPGA可以做点什么网站开发一般用哪个浏览器
  • Hive数据仓库:架构原理与实践指南
  • Azure OpenAI PTU 自动化运维完整指南
  • iOS 架构设计全解析 从MVC到MVVM与使用 开心上架 跨平台发布 免Mac
  • 深度学习-176-知识图谱技术之langchain与neo4j的嵌入向量Neo4jVector
  • Azure OpenAI PTU 容量自动调整方案:基于历史使用模式的智能伸缩
  • F033 vue+neo4j图书智能问答+知识图谱推荐系统 |知识图谱+neo4j+vue+flask+mysql实现代码
  • 深度学习-177-知识图谱技术之langchain与neo4j完整的RAG系统示例
  • seo网站平台wordpress自动生成网站地图
  • 《图解技术体系》Wonderful talk AI ~~人“涌现”
  • 浅谈ColchisFM地震正演分析在地震资料解释中的作用(六)
  • 动态规划or分治法——力扣53.最大子数组和
  • 【解决】蚁剑下载插件过慢、下载插件无法安装等问题
  • 在dify平台智能体工作流中迭代和循环如何选择?