第7章 复用类(组合,继承,代理)

复用的两种方式:1)组合:在新的类中产生现有类的对象

                          2)继承:按照现有类的类型来创建新类。

                          3)代理:将基类对象作为代理类的成员,而代理类有对应于基类的所有方法,各方法内使用基类对象成员调用基类的方法。

7.1 组合语法

    组合即将已有类的对象引用置于新类中。

    在自定义类中定义toString()方法比较特殊,当编译器需要一个String而只有一个对象时,就会去调用该类对象的toString()。

    例如:将一个String与一个对象相加,想得到一个新的String时,则编译器会试图去调用对象的toString()方法,然后再用toString()的返回值去与前面的String相连接。

    类中域为基本类型时能够自动初始化为0,而对象引用被初始化为null。初始化引用的可选位置如下:

    1)在定义类对象的位置

    2)在类的构造器中

    3)在使用这些对象之前(惰性初始化)

    4)使用实例初始化

7.2 继承语法

    同一个程序文件中可以为每一个类都创建一个main()方法,以便于测试。即使一个类只具有包访问权限,其public main()也是可以访问的。

    继承规则:父类的所有数据成员指定为private,方法成员指定为public。

    子类覆盖了父类的方法后,还是可以使用super再调用父类的该方法。

  7.2.1 初始化基类

    1)在创建子类对象时,会在其内部包装有一个基类子对象,而此时只有一种方法对基类子对象进行初始化,就是在子类的构造器中调用基类的构造器。

    2)在子类构造器执行前,必然会先去自动执行基类的构造器。 此时初始化的顺序为:

  1. 父类--静态变量或静态初始化块(静态变量和静态初始化块先后由其出现顺序决定。但静态初始化引用的静态变量,必须在其前面先定义
  2. 子类--静态变量或静态初始化块
  3. 子类static主函数内部(new 之前)
  4. 父类--普通变量或普通初始化块(new 以后,普通变量和普通初始化块先后由其出现顺序决定。但普通初始化引用的静态变量,必须在其前面先定义,包括父类的private数据成员也都会被初始化!!!,而且子类以后可以通过基类的public方法去访问它
  5. 父类--构造器
  6. 子类--普通变量或普通初始化块
  7. 子类--构造器

继承体系的类加载,static型的不管是static变量,还是static代码块都是属于类的.顺序嘛谁在前面先初始化谁.
类加载完毕,才会开始准备生成继承体系的对象,从顶层类开始Object,非static变量,非static代码块,构造器的调用,一个父类的对象出来了,处于可用状态,马上开始下一级的对象的生成工作,一直到没有子类的那个类的对象生成出来.
对象生成工作OVER!

    初始化的实际上在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零

  3)如果基类没有不带参数的默认构造器,或者想调用基类的带参数构造器,就必须在子类的构造器第一行用super(参数列表)来调用。

7.3 代理

     将基类对象作为代理类的成员,而代理类有对应于基类的所有方法,各方法内使用基类对象成员调用基类的方法。

7.4 结合使用组合和继承

  7.4.1 确保正确清理

    必须将清理动作置于finally子句中,以预防异常的出现。finally子句表示:无论发生什么事,一定要为执行其内部语句。

    清理顺序是:先执行子类的所有清理动作,顺序与生成相反,完了以后再执行父类的清理动作。

  7.4.2 名称屏蔽

    子类引入对父类的方法重载,完全可以与父类其他方法同时使用。而子类覆盖父类的方法后,还可以使用super来调用父类同名方法。

7.5 在组合与继承之间的选择

     组合通常用于想在新类中使用现有类的功能而非它的接口这种情形

     继承用于使用某个现有类,开发一个它的特殊版本。

7.6 protoected关键字

     用于控制类的继承者的访问权限

7.7 向上转型

    将子类引用作为实参,传给基类形参,即是向上转型。

    注意:基类中的形参虽然声明的类型时基类,但是实际上是子类对象,即调用重载方法时,实际优先使用的是子类的。

    当必须使用向上转型时,就要使用继承,否则可以选择组合。

7.8 final关键字

  7.8.1 final数据

    1) 当数据是编译期常量时,编译器就可以将其在编译期执行计算式时,直接代入,以减轻运行期负担

    在Java中,此种常量必须是基本数据类型,在其前加final,而且在定义时就进行赋值。

   2) 一个既是static,又是final的域只占据一段不能改变的存储空间。

    对于基本类型,final使数值不变,而对于引用,无法再使其指向另一个对象,而对象本身是可以改变的。

    3)当一个final域在运行期才能确定初值,它就无法成为编译期常量。

        带有恒定初始值的final static基本类型全用大写字母命名,字间用下划线隔开。       

    对于static的final域,则每个对象该域都相同。而普通final则各对象不同。

    4)对于final数组,与引用相同,只是指定的存储地址不可改变,而地址内的变量就可以改变。

空白final

    声明为final但又未在定义处给定初值的数据成员。但在构造器中一定要初始化。

final参数

    参数列表中指明为final后,则无法在方法中更改参数值。

7.8.2 final方法

    基类的final方法可以被继承,但是无法被子类重载或覆盖。

    同时编译器将该方法转为内嵌调用,提供效率。

final和private

    类中所有的private方法都隐含为final方法。子类即使有与父类private方法相同签名的函数,也不是重载或者覆盖,而是一个新方法。因为基类的private方法根本就不是子类能知道的接口。

7.8.3 final类

       不可被继承。其成员可是可不是final的。

7.9 初始化及类的加载

    类只在第一个对象被构建或者第一次访问类的staitc数据或方法时,才被加载,且只加载一次。加载第一步即static数据初始化。

7.10 总结   

    复用应优先考虑使用组合,继承只是复用接口,而组合更灵活。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值