问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

彻底理解Java内部类的使用(内部类代码实例详解)

发布网友 发布时间:2024-09-25 14:41

我来回答

1个回答

热心网友 时间:2024-11-24 14:04

前言

内部类相信大家都应该用过,但我也相信大家应该都只是很简单的使用。

所以今天,就来详细讲解内部类的使用,废话不多说,我们先赶紧来看吧。

在普通类中使用内部结构

先来看个示例:

Teacher类里面有个内部类Student:

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Students=newStudent();//实例化内部类的对象s.print();}//在Teacher类中的内部类classStudent{publicvoidprint(){System.out.println(Teacher.this.msg);//msg是Teacher类里面的属性}}}

测试类:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}

输出结果:

我是一名老师Processfinishedwithexitcode0

从整体的代码结构来讲,内部类的结构并不合理,所以内部类本身最大的缺陷在于破坏了程序的结构,但是破坏需要有目的的破坏,那么它也一定会有其优势,如果要想更好的观察出内部类的优势,就可以将内部类拿到外面来。我将上面的代码Student拿出来。

Teacher类:

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}

Student类:

publicclassStudent{privateTeacherteacher;publicStudent(Teacherteacher){this.teacher=teacher;}publicvoidprint(){System.out.println(this.teacher.getMsg());//msg是Teacher类里面的属性}}

测试:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}

输出结果:

我是一名老师Processfinishedwithexitcode0

我们折腾了半天主要的目的就是为了让Student这个内部类可以访问Teacher这个类中的私有属性,如果不用内部类的时候整体代码会非常的麻烦,所以可以得出内部类的优点:轻松的访问外部类中的私有属性。

需要注意的是:内部类虽然可以方便的访问外部类中的私有成员或私有方法,同理**,外部类也可以轻松访问内部类中的私有成员或私有方法**。

示例如下:

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent();//实例化内部类的对象student.print();System.out.println(student.info);}classStudent{privateStringinfo="我是一名学生";publicvoidprint(){System.out.println(Teacher.this.msg);}}}publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}

输出结果:

我是一名老师我是一名学生Processfinishedwithexitcode0

使用了内部类之后,内部类与外部类之间的私有操作的访问就不再需要通过setter,getter以及其他的间接方式完成了,可以直接进行操作,但是需要注意的是,内部类本身也属于一个类,虽然在大部分情况下内部类往往是被外部类包裹的,但是外部依然可以产生内部类的实例化对象,而此时,内部类实例化对象的格式如下:

外部类.内部类内部类对象=new外部类().new内部类();

在内部类编译完成之后会自动形成一个Teacher$Student.class类文件,其中“$”这个符号换到程序中就变为“.”,所以内部类的全称:“外部类.内部类”。内部类与外部类之间可以直接进行私有成员的访问,这样一来内部类如果要是提供有实例化对象了,一定要先保证外部类实例化了。

publicclassTest{publicstaticvoidmain(String[]args){Teacher.Studentstudent=newTeacher().newStudent();student.print();}}

如果此时Student类只允许Teacher类来使用,那么在这样的情况下就可以使用private进行私有定义。

这样,此时的Student类就无法再外部使用,即在test中的这条语句Teacher.Studentstudent=newTeacher().newStudent()就失效。

在抽象类和接口中使用内部结构

在我们的java之中,类作为最基础的结构体实际上还有与之类似的抽象类或者是接口,抽象类和接口中都可以定义内部结构。

接口中定义内部接口

我们现在定义内部接口:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}0publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}1

测试:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}2

输出结果:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}3接口中定义内部抽象类

下面我们继续观察一个内部抽象类,内部抽象类可以定义在普通类,抽象类,接口内部都可以。

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}4publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}5

测试:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}6

输出结果:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}3用内部类实现外部接口

内部类还有一些更为有意思的结构,即:如果现在定义了一个接口,那么可以在内部利用类实现该接口,在JDK1.8之后,接口中追加了static方法可以不受到实例化对象的控制,现在就可以利用此特性来完成功能。

接口内部进行接口实现:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}8

测试:

publicclassTest{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher();teacher.say();}}9

输出结果:

我是一名老师Processfinishedwithexitcode00

从上面可以看到,内部类是非常灵活的结构,只要你的语法满足了,各种需求都可以帮你实现!

static定义内部类static定义内部类

如果说现在内部类上使用了static定义,那么这个内部类就变成了外部类,static定义的都是独立于类的结构,所以该类结构就相当于是一个独立的程序类了。需要注意,static定义的不管是类还是方法只能够访问static成员,所以static定义的内部类只能够访问外部内中的static属性和方法。

我是一名老师Processfinishedwithexitcode01

这个时候的Student类是一个独立类,如果此时要想实例化Student类对象,只需要根据“外部类.内部类”的结构实例化对象即可

格式如下外部类.内部类内部类对象=new外部类.内部类();

测试:

我是一名老师Processfinishedwithexitcode02

输出结果:

我是一名老师Processfinishedwithexitcode0

所以以后如果发现类名称上提供有.,首先应该立刻想到这是一个内部类的结构,如果可以直接进行实例化,则应该立刻认识到这是一个static定义的内部类,但是static定义内部类的形式来讲并不常用,static定义内部接口的形式最为常用。

static定义内部接口我是一名老师Processfinishedwithexitcode04我是一名老师Processfinishedwithexitcode05我是一名老师Processfinishedwithexitcode06

测试:

我是一名老师Processfinishedwithexitcode07

输出结果:

我是一名老师Processfinishedwithexitcode08方法中定义内部类

内部类可以在任意的结构中定义,这就包括了:类中、方法中、代码块中。但在方法中定义内部类的情况比较多。

我是一名老师Processfinishedwithexitcode09publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}0

输出结果:

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}1

此时在say方法内部提供有Student内部类的定义,并且发现内部类可以直接访问外部类中的私有属性也可以直接访问方法中的参数,但对于方法中的参数直接访问时从JDK1.8开始支持的。而在JDK1.8之前**,如果方法中定义的内部类要想访问方法中的参数则参数前必须追加final。**

之所以取消这样的*是为了扩展函数式编程准备的。

匿名内部类

匿名类是一种简化的内部类的处理形式,其主要是在抽象类和接口的子类上使用的。

接口和抽象类是一样的。

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}2publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}3publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}4

如果说现在Study接口中的XiaoMing子类只使用唯一的一次,那么是否还有必要将其定义为单独的类?那么在这样的要求下就发现这个时候定义的子类是有些多余了,所以就可以利用内部类的形式来解决此问题。

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}2publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}6

匿名内部类不一定要在抽象类或接口上,但只有在抽象类和接口上才有意义。有些时候为了更加方便的体现出匿名内部类的使用,往往可以利用静态方法做一个内部类的匿名内部类实现。

在接口中直接定义匿名内部类。

publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}7publicclassTeacher{privateStringmsg="我是一名老师";//只能在类内部访问publicvoidsay(){Studentstudent=newStudent(this);//实例化内部类的对象student.print();}publicStringgetMsg(){returnthis.msg;}}8

与内部类相比匿名内部类只是一个没有名字的只能够使用一次的,并且结构固定的一个子类。

总结:

方法,类,抽象类,接口,代码块中都可以定义内部结构——类,抽象类,接口。

本文主要讲了如何在内部类中使用内部类和接口中使用内部类以及如何使用static修饰的内部类和如何在方法中使用内部类。看完这篇相信你对内部类的理解更加深入了。

作者:初念初恋

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
养胃的药最好的是什么啊 婴儿积食发烧不愿吃药怎么办 板门穴位在哪个部位 手机设置放偷看的方法? 凝结水回收器生产厂家? 个人账户养老金预测公式:现有5万元,缴费20年,能领多少钱? 临沂比较有名的男装品牌 呼伦贝尔市悦动网络科技有限公司怎么样? 呼伦贝尔中汇实业有限公司怎么样? 呼伦贝尔油玉不绝电子商务有限公司怎么样? 吊钟花什么时候扦插最好 吊钟花哪个时候扦插最好 2024年最值得选择的国产手表十大品牌 Win10开始菜单打不开需重启“桌面窗口管理器”吗? Win10开始菜单打不开后如何重启桌面窗口管理器? win10如何恢复窗口程序 淘宝买东西为什么会显示虚拟手机号码。 虚拟号码是怎么回事?有什么优势和缺点呢? 手机买之前被虚拟认证了,不是我的信息,可以改吗 通灵蜂胶基本信息 红柚子皮发红是注射染色吗 深度剖析!广东工业大学轻工化工学院考研考情(含拟录取名单、国家线... 广东工业大学 暨南大学 广州大学 广东外语外贸大学 福建农林大学 厦门... 广东工业大学研录取人数包括推免的吗 打蚊子的作文500字 描写蚊子的作文 蚊子与老奶奶作文500个字 爱奇艺会员话费自动续费怎么关闭,我没有找到在哪里,手机版的,可以告诉... 手机怎样取消爱奇艺会员自动续费? 为什么我找不到取消自动续费这个功 ... 我不是爱奇艺会员,怎么给我发的这个信息,咋取消,我在爱奇艺账户里没看到... 液晶显示器屏幕刷新频率只有59、60。(详细点加分) 我看别人都有75.85神 ... 看到如此详细的Java内部类,我泪目了 吊钟海棠几月扦插 java中方法中的内部类不能访问该方法的局部变量,有什么道理吗? ...定制的海鸥手表,发给我们时候发现LOGO SEAGULL的A是斜的 SEA和GULL... 婚礼请贴是什么意思? 2022年浙江省独生子女补贴标准新消息 浙江独生子女补贴怎么领取_百度... 为什么重启电脑后桌面文件会消失? prscrn/sysrq 印屏幕 这个键盘按键抓去的截图自动保存在什么地方... 如何做好施工现场临时用电标准化管理 这个问题怎么查?工地临时用电的~ Androidsdk包(androidSDK下载安装) androidsdk怎么下载? 手游模拟器sdk认证失败? 一直喜欢beyond的歌,关于beyond你们懂多少。我出生那年他的生命在离去... 36201千克是多少克 天语小黄蜂w619云帐号at3620g2w密码是多少 为什么很多男人看我的眼神怪怪的 樱桃什么时候打药 梦见一条疯狗想咬自己和家人。但被一群不认识的人拿枪杀死了... 笔记本突然发出很强的噪音 然后黑屏,关机键也失灵了。声音非常刺耳...