类要么被设计成专用于继承(并辅以清楚的文档),要么就完全禁止继承

item 16提到过,继承一个本软件包以外的类是危险的,除非它被设计成专用于继承。这节就是讲一个"专用于继承的类"该是什么样子。

首先,这个类必须用文档注明它自己对"可覆盖方法"的使用情况(所谓"可覆盖方法",就是非final的、并且是public或protected的方法)。比如:某个方法调用了哪些可覆盖方法,调用顺序怎样,它们的返回值对后续处理将产生怎样的影响。还应注明在哪些情况下,可覆盖方法会被调用。比如调用者可能是后台运行的其他线程或静态初始化代码。

昨天下午几乎啥都没干,就在visual studio的build、rebuild,还有git的fetch、pull和rebase中度过。

开始做.NET有两个月了,开发写代码从一开始就没有障碍,但效率却一直离Java+Eclipse的水品差了十万八千里。debug时跳转一行代码,vs都经常会拼了老命重编译一堆莫名其妙的东西;改动一个配置文件,重编译相关模块还不够,经常要全方案重建;vs默认快捷键渣渣等于没有,加了resharper之后也还是离不开鼠标;动不动就因为某个dll不一致而编译失败,又要全方案清空重建;debug没有jump to frame功能,跑过了就要重新开始。。。我越来越经常要抑制住骂娘的冲动了。

相对于继承(inheritance),应更优先使用组合(composition)

继承是一种非常强大的代码重用方式,但它并不总是最好的方式。

在同一个软件包内可以安全地使用继承,这是因为父类和子类都在同一群开发者的维护之下。或者父类是被设计为专用于继承,那么同样可以安全地使用。相反,跨软件包去继承普通的类,则可能是危险的。

不同于方法调用,继承会破坏类的封装。换言之,子类必须依赖于父类的实现细节才能正常运行,而父类的实现完全可能在不同版本之间发生变化,这会破坏子类代码。

比如下面的代码。继承了HashSet类,增加一个计数器,以统计Set中曾加入过的元素总数:

今天成绩出来了。

听力:8
阅读:8.5
写作:6.5
口语:7

真是悲催的分数。本来如果是普通留学什么的,这分数也够了,但我要搞的偏偏是技术移民,需要雅思每项都过7分。。。于是写作差的那0.5就把我绊住了。郁闷,很可能要重考。

这个博客已经建立两年多,但真正开始写是最近一个多月。之前一直没有遇到性能问题,想必是因为数据量小,只有个位数的文章,所有访问都是飞快。

现在文章即将过百,访问明显变慢了。前不久有国内的朋友抱怨访问速度太慢,查了一下发现,国内的问题应该是dns、路由和墙共同作用的结果。在http://ping.chinaz.com/测速得到:

线路耗时最短节点耗时最长节点平均耗时
所有线路 英国[海外] 深圳[联通] 3528毫秒
电信 四川遂宁[电信] 江西[电信] 3846毫秒
多线 浙江[多线] 安徽[多线] 3437毫秒
联通 安徽滁州[联通] 深圳[联通] 4832毫秒
移动 山东[移动] 深圳[移动] 3222毫秒
海外 英国[海外] 日本[海外] 2307毫秒

保持最小的可变性
说一个类"不变",就是说它的所有对象在运行时不可以被更改。Java系统库中有很多这样的例子,比如String、类封装的基本数据类型、BigInteger和BigDecimal等等。想创建一个不变类,需要遵循下面5条原则:
1. 不能提供任何改变对象状态的方法(比如setter)。
2. 保证类不能被继承,否则子类将可以通过覆盖父类方法来改变对象状态。常用的做法是把类声明为final,还有另一种方法是隐藏或保护所有的构造函数,只提供一个静态factory方法来创建对象(参见item 1)。
3. 所有属性都声明为final。
4. 所有属性都声明为私有。

第5页 共19页