Thinking in Java第六章阅读小结

                                                                  第六章 复用类
通过创建新类来复用代码,而不必再重头开始编写。可以使用别人已经开发并调试好的类。
使用类而不破坏现有程序代码的两种方法:(1)在新的类中产生现有类的对象。由于新的类是由现有类的对象所组成,所以这种方法称为 组合。该方法只是复用了现有程序代码的功能,而非它的形式。(2)按照现有类的类型来创建类。无需改变现有类的形式,采用现有类的形式并在其中添加新代码。这种方法称为 继承,编译器可以完成大部分工作。
 
6.1 组合语法:
   只需将对象引用置于新类中即可。对于基本类型数据,可以直接定义。对于非基本类型的对象,必须将其引用置于新的类中。如果想初始化这些引用,可以在代码的下列位置进行:
(1)       在定义对象的地方,在构造器初始化之前执行
(2)       在类的构造器中
(3)       在正要使用这些对象之前,这种方式称为“惰性初始化”
   toString()方法的使用:每个基本类型的对象都有一个toString()的方法,而且当编译器需要一个String而你却只有一个对象时,该方法就会被调用。每当想要使所创建的类具备这样的行为时,仅需要编写一个toString()方法即可。
 
6.2 继承语法:
   当创建一个类时,总是在继承。因此,除非已明确指出要从其他类中继承,否则就是在隐式的从Java的标准根类Object进行继承。关键字extends
 
   1 .例程中涉及到的Java 的一些特性:
(1)       处理String对象的操作符:+ 以及 +=
(2)       可以为每个类都创建一个main()方法,一般都建议以这种方式来编写程序代码,以便测试代码被包装在类中。即使一个程序中含有多个类,也只有命令行所调用的那个类的main方法会被调用,只要这个mian()是Public,其所属的类是否是public则不用考虑。这种在每个类中都设置一个main()方法的技术可以使每个类的单元测试都变得简便易行。完成单元测试后,也无须删除main(),可以将其留下待下次测试。
(3)       为了继承,一般的规则是将所有的数据成员都指定为private,将所有的方法都指定为public(protected成员也可以借助导出类来访问)。特殊情况下必须作出调整。
(4)       导出类继承基类后自动获得基类的方法,尽管看不到这些方法在导出类中的显示定义。
(5)       使用基类中定义的方法及对它进行修改是可行的。修改可用override方法。在子类中调用基类方法可用关键字super,如super.scrub()
(6)       在继承的过程中并不一定非得使用基类的方法,也可以在导出类中添加新方法,其添加方式与在类中添加任意方法一样,即对其加以定义即可。
(7)       对于一个导出类对象,即可以调用导出类的方法,也可以调用基类所有可用方法。
 
2 .初始化基类
   当创建了一个导出类的对象时,该对象包含了一个基类的子对象。这个子对象与你用基类直接创建的对象是一样的。二者区别在于,后者来自外部,而基类的子对象被包装在导出类对象内部。
   对基类子对象的正确初始化也是至关重要,仅有一种方法来保证这点:在构造器中调用基类构造器来执行初始化,而基类构造器具有执行基类初始化所需要的所有知识和能力。
(1)       缺省构造器:Java会自动在导出类的构造器中插入对基类构造器的调用。
(2)       带参数的构造器:如果类没有缺省的参数,或者想调用一个带参数的基类构造器,就必须使用关键字super显示的编写条用基类构造器的语句,并配以适当的参数列表。调用基类构造器必须是你在导出类构造器中要做的第一件事。
(3)       捕捉基类构造器异常:将对基类构造器的调用置于导出类构造器的第一件事,这种做法可以防止导出类构造器捕捉任何来自基类的异常。
 
6.3 结合使用组合和继承:
 
   1 .确保正确清理:
       除了内存回收使用垃圾回收器,其他的东西需要用一个显示的方法来做必要的清理,必须将清理动作置于finally字句中,以预防异常的出现。Finally表示后面的代码一定会被执行。
       在清理方法中,还必须注意对基类清理方法和成员对象清理方法的调用顺序,以防某个子对象依赖于另一个子对象情形的发生。一般而言,所采用的形式应该于C++编译器在其析构函数上所施加的形式相同。
 
   2 .名称屏蔽:
      如果Java的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽其在基类中的任何版本。
 
6.4 在组合与继承之间选择:
组合和继承都允许在新的类中放置子对象,组合是显示的这样做,而继承是隐式的这样做。
组合技术通常用于想在新类中使用现有类的功能而非它的接口。即,在新类中嵌入某个对象,让其实现所需要的功能,但新类的用户看到的只是为新类所定义的接口,而非所嵌入对象的接口。为取得此效果,需要在新类zhog嵌入一个现有类的private对象。有时,允许类的用户直接访问新类中的组合成分,此时将成员对象声明为public。
在继承的时候,使用某个现有类,并开发它的一个特殊版本。通常这意味着你在使用一个通用类,并为了某种特殊需要而将其特殊化。
使用组合还是使用继承可以这么判断:is a à继承    has a à组合
 
6.5 protected 关键字:
就类的用户而言,它是不可访问的,但是对于任何继承于此类的导出类或其他任何位于同一个包内的类来说,它确实可以访问的。
 
6.6 增量开发:
引入新代码而不会在现有代码中引发bug
 
6.7 向上转型:
新类是现有类的一种类型,把子类对象当作父类对象来使用
由于向上转型是从一个比较专用类型向较通用类型转换,所以总是很安全的。也就是说,导出类是基类的一个超级,它可能比基类含有更多的方法,但必须至少具备基类中所含有的方法。
也可以执行与向上转型相反的“向下转型”,但这里涉及到一个难题,在第十章讨论。
慎用继承技术:到底改用组合还是用继承,一个最清晰的判断方法就是问一问自己是否需要从新类向基类进行向上转型。如果必须向上转型,则继承是必要的。但如果不需要,则应当好好考虑自己是否需要继承。
 
6.8 final 关键字:表示不能被改变
 
   1 .final 数据:
      (1)一个永远不改变的“编译时常量”。编译器可以将该常量代入任何可能用到它的计算式中,即可以在编译时执行计算式,这减轻了一些运算时的负担。这类常量必须是基本数据类型,并且以关键字final表示,在对这个常量进行定义的时候,必须对其进行赋值。
     (2)一个在运行时被初始化的值,而你不希望它被改变。
 注意:编译时常量全用大写字母命名,并且字与字之间用下划线隔开。而运行时初始化的值不用大写字母表示。
 空白final:指被声明为final但又未给定初值的字段。无论什么情况,编译器都确保空白final在使用前必须被初始化。必须在字段的定义处或者每个构造器中用表达式对final进行赋值,这正是final字段在使用前总是被初始化的原因所在。
 final参数:这意味着你无法在方法中更改参数引用所指向的对象。你可以读参数,但却无法修改参数。
 
  2 .final 方法:
     有两个原因使用final方法:第一个原因,把方法锁定,以防任何继承类修改它的含义。这是出于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。第二个原因,是效率,如果将一个方法指明为final,就是同意编译器将针对该方法的所有调用都转为inline调用。
     Private方法都隐式的指定为是final的。
 
  3 .final 类:
不允许被继承,断子绝孙。
Final类的字段可以根据个人意愿选择为是或不是final,不论类是否被定义为final,相同的规则都适用于定义为final的字段,然而,final类中所有的方法都隐式的指定为是final的,因为无法覆盖它们。在final类中给方法添加final修饰词不会增添任何意义。
 
6.9 初始化及类的加载:
 (1)父类静态定义初始化
 (2)子类静态定义初始化
 (3)父类定义初始化
 (4)父类构造初始化
 (5)子类定义初始化
(6)子类构造初始化
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值