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

类和对象的基本认识之内部类

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

class Teacher{private String name;private int age;class Friend{//内部类}}

内部类必须在类的里面,不然即使它们在同一个文件,也不是内部类,并且内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件 ,其中外部类的字节码文件名为Teacher.class,而内部类的字节码文件为Teacher&Friend.class。有没有发现这些字节码文件名的规律?是不是类名后加一个.class啊,如果是内部类的话,则在前面加上外部类的名和&就行。那么内部类里面能不能再添加一个内部类呢?当然可以,并且它的字节码文件和前面的规律一样。都是在外部类名后面加&,比如Teacher&Friend&Student.class。一个类里面可以有多个内部类,但是还是不建议在类里面定义多个内部类。

 内部类的分类

           根据内部类定义的位置不同,一般可以分为以下几种形式:
1. 成员内部类(普通内部类:未被static修饰的成员内部类 和 静态内部类:被static修饰的成员内部类)
2. 局部内部类(不谈修饰符)、匿名内部类
注意:内部类其实日常开发中使用并不是非常多,日常开始中 使用最多的是匿名内部类。
实例内部类:即未被static修饰的成员内部类。
class Teacher{private String name;private int age;class Friend{private String name;private int age;private int height;}}

既然被叫做成员内部类,那么是否有和成员变量一样的性质呢?我们都知道,当我们创建一个对象时,里面的成员变量都会被创建,那么如果我创建外部类对象时,内部类是否会被创建呢?答案是不会,内部类对象需要我们手动创建,那么我们可不可以单单只创建实例内部类对象而不创建外部类对象呢?这可不行,它是属于外部类的,怎么可能外部类对象(儿子)还没生出,就生出内部类对象(孙子)呢(滑稽)。那么我们应该如何创建内部类对象呢?我们应先创建外部类对象,然后用对象名来(.)来创建内部类对象。

Teacher teacher = new Teacher();
Teacher.Friend friend1 = teacher.new Friend();
Teacher.Friend friend2 = new Teacher().new Friend();

对象名前面的就是它的类型,那么可不可以不加Teacher呢?很可惜,不行,如果你不写前面的话,那我们怎么确定它到底是外部类还是内部类,是谁的内部类啊。如果内部类中的成员变量的名字与外部类的成员变量的名字相同的话,我们如何在内部类中使用外部类变量,我们不可能用super,虽然我前面说它们是父子,但它们关系却并不是父子关系,因此我们得使用其他方法去使用,要在内部类中使用外部类变量的话,我们只需这么写

name = Teacher.this.name;//内部调用外部,后面的是内部类成员

我们得知道,实例内部类的注意事项,才能更好的使用它

1. 外部类中的任何成员都可以在实例内部类方法中直接访问
2. 实例内部类所处的位置与外部类成员位置相同,因此也受publicprivate等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问。
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

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

静态内部类与实例内部类的用法大差不差,只有两个注意事项。

1. 在静态内部类中只能访问外部类中的静态成员
      
2. 创建静态内部类对象时,不需要先创建外部类对象
Teacher.Student student = new Teacher.Student();
Teacher teacher = new Teacher();
Teacher.Student student1 = teacher.new Student();//报错

若static修饰成员变量的话,虽然java不建议通过对象来使用静态成员变量,但是任然可以正常运行,不过如果static修饰内部类的话,则不能通过对象名来使用内部类。

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

class Teacher{public void method(){class Frind{}}}
【注意事项】
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被publicstatic等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用

匿名内部类:都被称为匿名了,那么肯定没有类的名字,是通过实现接口来创建内部类,这个在实际中运用的最多,后续我们再说。

new Iswim(){@Overridepublic void swim() {}
};

这个就是匿名内部类,{}里面的是接口Iswim的方法的重写,{}里面才是被匿名的类的主体。

http://www.lryc.cn/news/43525.html

相关文章:

  • 【操作系统】进程和线程是什么之间是如何通信的
  • setup、ref、reactive、computed
  • 【Gem5】有关gem5模拟器的资料导航
  • 【CSS】清除浮动 ① ( 清除浮动简介 | 清除浮动语法 | 清除浮动 - 额外标签法 )
  • Shell test 命令
  • pytorch项目实战之实时人脸属性检测系统
  • JS和Jquery
  • Linux设置固定IP
  • 面试准备啊
  • 机器人工程专业师生的第二张名片
  • 【云原生之企业级容器技术 Docker实战一】Docker 介绍
  • 【Microsoft】与 Bing AI 进行 ⌈狂飙⌋
  • PyDolphinScheduler发布4.0.2版本,修复无法提交工作流到DolphinScheduler 3.1.4的问题
  • go-cqhttp安装使用
  • 论文阅读和分析:Hybrid Mathematical Symbol Recognition using Support Vector Machines
  • 05期:面向业务的消息服务落地实践
  • 代码随想录|day26|回溯算法part03● 39. 组合总和● 40.组合总和II● 131.分割回文串
  • linux-文件切割-splitcsplit
  • USB键盘实现——设备限定描述符(五)
  • 【C++】map和set(一文拿捏,包教包会)
  • 爬虫Day2 正则表达式
  • LeetCode-0324~28
  • Vue2自己封装的基础组件库或基于Element-ui再次封装的基础组件库,如何发布到npm并使用(支持全局或按需引入使用),超详细
  • 【开发】中间件——MongoDB
  • C++进阶 — 【C++11】
  • Mac安装Homebrew
  • 【详细】利用VS2019创建Web项目,并发送到IIS,以及IIS与ASP.NET配置
  • FasterRcnn,Yolov2,Yolov3中的Label Assignment机制 和 ATSS
  • 使用Java技术WebSocket创建聊天、群聊,实现好友列表,添加好友,好友分组,聊天记录查询功能。
  • 【Redis07】Redis基础:Bitmap 与 HyperLogLog 相关操作