java内部类

* 引例
 * 我们现在做一个应用程序,需要描述一台电脑中的CPU,对于电脑而言,该怎么去描述这个CPU呢?
 *
 * 分析:
 * 我们可以创建两个类,一个描述Computer,一个描述CPU。
 * 但这样明显是有问题的:
 * 1.CPU是电脑中最重要的组件,但它脱离电脑存在就是一粒沙子。
 *      这意味着CPU对象,应仅存在于Computer内部。
 *      这个按照以往的知识语法是做不到的.
 *
 * 2.CPU可以控制计算机的一切硬件资源。
 *      这意味CPU对象能够操控,Computer类中的所有成员,无论私有。
 *      需求: 一个类的对象要能够无条件访问另外一个类的所有成员,无论私有
 *      这个按照以往的知识语法也是做不到的.
 *
 * 定义普通类CPU是不能完成需求的,因为:
 *      1.普通类没有私有概念,不可能控制仅能在Computer内部创建对象。
 *      2.普通类不可能直接访问,其它类的私有成员。
 * 显然CPU类不应该是一个普通类,不应该是一个独立的类
 *      ---> 不再将CPU类定义为一个独立的类
 *      而是将它放入Computer类的类体中,可以近似的看成是一个Computer类的成员
 *      ---> CPU类近似看成Computer类的成员,于是:
 *
 *      1.在其它类内部的类,就有了私有概念,就有了四种访问权限。
 *          只需要在内部私有化一个类,那么在外界就无法创建它的对象了。
 *      2.既然已经成为了成员,成为了"自己人",那么就不再受限于权限控制了
 *          内部类就可以访问包裹它的类的所有成员,包括私有。
 *
 * 上述两条,其实就是(成员)内部类的主要特点。也说明了使用内部类的主要场景:
 *      1.内部类是一种比类更加极致的封装思想体现
 *          内部类的成员不仅被类自身保护,还被包裹着它的类保护。
 *
 *      2.内部类和包裹它的类互相成为了"好兄弟"
 *          互相访问成员都不受访问权限限制。
 *
 * 当你有以上使用场景时,就可以考虑使用内部类了。
 * 学习内部类之前,声明:
 *      内部类更多是一个为了精巧的设计而诞生的语法,不学习它,Java很多代码都看不懂
 *          比如典型的集合体系
 *      但是我们不是天生就会写精巧设计的,需要时间积淀
 *
 * 学习的要求:
 *      学习内部类,不要求会使用,不要求会去做设计
 *      只要求看懂语法,会用语法就可以了
 *
 * 为了上课方便,我们需要统一口径,在内部类课程当中,我们统一规定:
 * 像CPU这种,定义在别的类的内部的类,我们称之为内部类。(inner)
 *Computer这种,包裹内部类的,我们称之为外围类。(enclosed)
 * Demo这种类我们称之为外部类。(outside)
 *
* 成员内部类
 * 成员内部类是最普通的内部类
 * 它直接定义在另一个类的成员位置,可以近似看成该类的一个成员。
 *
 * 语法:
 * //外围类
 * [访问权限修饰符] class EnclosedClazz{
 * //成员内部类
 *   [访问权限修饰符] class InnerClazz{
 *  }
 * }
 *
 * 成员内部类的自身特点
 * 主要从以下几个角度分析:
 *      1.访问权限修饰符
 *          四种访问级别皆可
 *          而单独定义的class只有两种访问级别
 *          既然使用内部类,普通都是为了封装,隐藏,保护类
 *          所以内部类的访问权限,往往都是私有的.
 *
 *      2.成员特点
 *          它仍然是一个类,虽然它是内部类
 *          和普通类的成员相比,成员内部类当中是没有静态声明的:
 *              a.没有静态成员变量
 *              b.没有静态成员方法
 *              c.没有静态代码块
 *           注意:
 *              允许定义全局常量,但是不允许触发类加载的全局常量
 *              也就是说只能定义字面值常量赋值的全局常量
 *
 *           除此之外,和普通类一样
 *           有构造器,有构造代码块
 *
 *      3.继承和实现
 *          既然它是一个类,虽然它是内部类
 *          但是照样继承,照样实现
 *          在开发中,成员内部类的继承和实现可以根据具体情况,具体对待
 *
* 成员内部类怎么用?
 * 类是创建对象的模板,定义成员内部类,最终还是需要创建对象的,还是需要new对象的
 *
 * 成员内部类最重要的特点/成员内部类和外围类的关系:
 *      成员内部类可以看成外围类的一个成员。
 *      要想得到成员内部类对象,必须先创建外围类对象。
 *      这是因为: 成员内部类对象的成员变量列表中,会持有外围类对象的引用!!!
 *      成员内部类和外围类之间是强依赖关系,成员内部类依赖于外围类,反过来不成立.
 *
 * 除以上关系外,还要铭记(这不是成员内部类独有的特点):
 *      内部类和外围类之间是"好兄弟",它们之间的访问不受权限限制.
 *
 * 明确以上两点,现在来学习一下成员内部类的访问特点
 * 主要从以下四个角度研究:
 *      1.成员内部类内部访问外围类成员(重要)
 *          访问的位置: 成员内部类的成员方法中(没有静态方法)
 *          成员内部类的成员方法中存在几个对象?
 *              首先肯定存在this指向当前对象,所以必然有自身类对象
 *              除此之外还有外围类对象
 *              有两个对象
 *           既然有两个对象,那么访问外围类成员如何访问呢?
 *              直接访问,而且访问不受权限限制.
 *
 *              极端情况下,会出现外围类,成员内部类同名成员变量,那怎么办呢?
 *              语法:
 *              在成员内部类的成员方法中
 *              this指向当前自身对象
 *              外围类类名.this指向外围类对象
 *
 *
 *      2.外围类访问成员内部类成员成员(重要)
 *          访问的位置:
 *              外围类是一个普通类
 *              它有两种访问位置:
 *              成员方法以及静态方法
 *
 *          这两个访问位置是有区别的
 *              1.外围类的成员方法中访问成员内部类成员
 *              这里存在什么对象?
 *              只有this指向当前自身对象
 *              外围类对象并不依赖于成员内部类
 *              所以这里不存在成员内部类对象
 *              所以想要访问它的成员,必须创建它的对象
 *              如何创建呢?
 *              要想得到成员内部类对象,必须先创建外围类对象。
 *              在外围类对象的基础上,再创建成员内部类对象
 *              这里已经存在外围类对象了,所以可以直接创建成员内部类对象.
 *
 *              2.外围类的静态成员方法中访问成员内部类成员
 *              没有任何对象, 没有外围类对象
 *              所以这里不存在成员内部类对象
 *             所以想要访问它的成员,必须创建它的对象
 *                如何创建呢?
 *                要想得到成员内部类对象,必须先创建外围类对象。
 *               在外围类对象的基础上,再创建成员内部类对象
 *               对象创建完毕后,该咋访问就咋访问.
 *
 *      3.外部类访问成员内部类成员(多数情况下访问不到,不重要)
 *      首先访问的全程都要受权限限制
 *      其次外部类中,无论是成员方法还是静态方法
 *      都没有区别
 *
 *      4.成员内部类访问外部类成员(不重要,受权限限制)
 *          可以访问,该咋访问咋访问
 *          受权限限制.
 *
* 成员内部类和外围类是强依赖关系,成员内部类对象会持有外围类对象的引用
 * 那么静态内部类和外围类之间,又有什么关系呢?
 * 没有关系
 * 静态内部类和外围类就是独立的两个类,只不过静态内部类借用外围类保护自己
 *
 * 静态内部类仍然定义在类的成员位置,它的语法是:
 * //外围(普通)类
 * [访问权限修饰符] class EnclosedClazz{
 * // 静态内部类访问权限修饰符,有四个,和普通成员一样
 *   [访问权限修饰符] static class NestedClazz{
 *  }
 * }
 *
 * 静态内部类的自身特点
 * 依然主要从以下几个角度分析:
 *      1.访问权限修饰符
 *          和成员内部类一样,有四种访问级别
 *          四种皆可用
 *      2.成员特点
 *          静态内部类就是一个普通类放入另外一个类的类体中
 *          所以它和普通类的成员没有任何区别
 *
 *          从这个角度出发,静态内部类相比较于成员内部类
 *          静态内部类是更灵活的,不受外围类限制,单纯隐藏类
 *
 *      3.继承和实现
 *          可以继承,可以实现,了解即可
 *
 * 静态内部类的访问特点:
 * 主要从以下几个角度研究:
 *
 *      1.静态内部类内部访问外围类成员
 *          直接创建外围类对象即可,访问不受权限限制.
 *
 *      2.外围类访问静态内部类成员
 *          直接创建静态内部类对象即可,访问不受权限限制.
 *
 *      3.外部类访问静态内部类成员(了解即可)
 *          全程受权限限制
 *          而且注意:
 *              这里访问静态内部类成员,不再需要创建外围类对象了
 *              直接new创建静态内部类对象即可
 *          语法:
 *              EnclosedClazz.NestedClazz nc = new EnclosedClazz.NestedClazz();
 *
 * 静态内部类访问外部类成员
 *
* 局部内部类是定义在一个方法或者一个作用域里面的类
 * 简单来说,将局部内部类看成是局部变量即可
 * 该局部内部类的有效范围仅在作用域内部。
 * (这意味着要创建它的对象,必须在作用域内部创建)
 *
 * 从语法和具体使用上看,局部内部类和成员内部类很相似
 * 有点类似于直接把一个成员内部类放进局部位置,语法是:
 *局部内部类语法
 * // 局部位置
 * class Inner{
 * }
 * // 局部位置
 *
 * 局部内部类自身特点
 * 主要从以下几个角度分析:
 *      1.访问权限修饰符
 *          局部内部类的作用范围就仅在大括号内部
 *          它不需要做权限控制
 *          除此之外,它也不能用static修饰
 *          这些都很类似于局部变量
 *
 *      2.成员特点
 *          局部内部类的成员特点和成员内部类完全一模一样
 *          没有static声明,但是可以定义不触发类加载的全局常量
 *
 *      3.继承和实现(重点)
 *          开发中使用局部内部类主要的用途就是
 *          用它继承/实现
 *
 * 在说明以下访问特点之前,我们要明确两个点:
 *      1.局部内部类仅在定义它的作用域内部生效,这意味着即便是外围类
 *          也不能任意访问它
 *          只能在作用域内部去访问/使用它
 *
 *      2.内部类和外围类是"好兄弟"的原则,在局部内部类中发生了改变:
 *          局部内部类仍然可以无条件访问外围类(不受限制)
 *          外围类只能在作用域内部访问,作用域之外是不能直接访问这个局部内部类的
 *
 *局部内部类的访问特点,我们仍然主要从以下几个角度研究:
 *      1.局部内部类内部访问外围类(重点)
 *          可以正常访问,并且局部内部类没有静态声明
 *          所以只能在成员方法中访问外围类
 *
 *          (重点)局部内部类处在外围类的不同方法时,效果是不同的:
 *              a.外围类静态方法中的局部内部类
 *                  就是一个单纯的内部类,和外围类对象之间没有任何关系(类似于静态内部类)
 *
 *              b.外围类成员方法中的局部内部类
 *                  这时局部内部类对象,会持有外围类对象的引用,作为它的成员变量(类似于成员内部类)
 *
 *      2.外围类访问局部内部类成员(一般)
 *          在作用域内部创建对象,可以无条件访问
 *          作用域之外不能直接访问局部内部类
 *
 *      3.外部类访问局部内部类成员(了解)
 *          外部类肯定无法直接访问局部内部类
 *      4.局部内部类访问外部类成员(了解)
 *          可以访问,创建对象,受权限限制
 *
 * 以上语法,1是相对比较重要的,但是总体而言,都不是很常用.
 *
* 局部内部类经常使用在以下两个场景中:
 *      1.方法需要返回一个对象,返回值类型是引用数据类型时。
 *      方法需要返回一个对象时,可以在方法的局部位置写一个 局部内部类 继承/实现外部的类/接口,创建对象后作为返回值。这是因为方法的返回值可以是返回值类型的对象,也可以是子类对象(当返回值类型是引用数据类型时)。
 *
 *      2.方法需要传入一个对象,形参数据类型是引用数据类型时。
 *
 *      方法需要传入一个对象实参时,可以在调用方法的位置定义一个 局部内部类 来继承/实现外部的类/接口,创建对象后作为方法的实参传入。这是因为方法的实参可以是形参类型的对象,也可以子类对象(当返回值类型是引用数据类型时)。
 *
 * 使用局部内部类的优点:
 *      1.绝对对外界隐藏,封装。
 *      2.相比较于传统的定义类,然后创建对象,它相对更加简洁省事。
 *
 * 缺点:
 *      1.这个类是一次性的。
 * 综上,假如在局部位置需要一次性的使用某个对象
 * 可以使用局部内部类创建它
 * 但是如果多次在不同的方法中使用,使用局部内部类就得不偿失了。
 *
 * 以上,局部内部类的语法还是有些麻烦了,这是局部内部类使用的最大限制
 * 在实际开发中,很少直接使用局部内部类
 * 因为匿名内部类,Lambda表达式语法更简洁,基本取代了它.
 *
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长安有故里y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值