将公共操作和域放在超类

比如将姓名域放在 Person 类中,而不要放在 Employee 和 Student 中的原因。

不要使用受保护的域 (protected)

虽然子类可以直接访问父类中的 protected 域,但是 protected 机制并不能带来更好的保护。

  1. 第一,子类集合是无限制的,任何一个人都能够由某个类派生一个子类,并编写代码以直接访问 protected 的实例域,从而破坏了封装性。
  2. 第二,在 Java 程序设计语言中,在同一个包中的所有类都可以访问 proteced 域,而不管它是否为这个类的子类。

    使用继承实现 is-a 关系

    使用继承很容易达到节省代码的目的,但有时候也被人们滥用了。比如,有人将钟点工继承自雇员,但这是有问题的。钟点工与雇员之间不属于 is-a 关系。钟点工不是特殊的雇员。

    除非所有继承的方法都有意义,否则不要使用继承

    假设想编写一个 Holiday 类。毫无疑问,每个假日也是一日,并且一日可以用 Gregorian Calendar 类的实例表示,因此可以使用继承。 ``` class Holiday extends GregorianCalendar {…}
  1. 但是 GregorianCalendar 类中有一个共有方法 `add()` 会将假日转换成非假日,所以这里使用继承不太合适。<br />可以继承 LocalDate ,就不会出现这个问题
  2. ### 在覆盖方法时,不要改变预期的行为
  3. 在覆盖一个方法的时候,不应该毫无原由地改变行为的内涵。<br />应该符合置换原则,原则上能用父类调用的方法,使用子类也没有问题。<br />但也会出现一些问题,置换原则要求 Manager.equals 不处理 bonus 域,因为 Employee.equals 没有它。实际上,凭空讨论这些问题毫无意义。关键在于,在覆盖子类中的方法时,不要偏离最初的设计想法。
  4. ### 使用多态,而非类型信息
  5. 如果你写出了这样的代码:

if (x is of type1) action1(x); else if (x is of type2) action2(x);

  1. 应该考虑使用多态性。将这个概念放在超类或接口中,就可以调用:

x.action();

``` 以便使用多态性提供的动态分派机制执行相应的动作。

不要过多地使用反射

反射机制使得人们可以通过在运行时查看域和方法,让人们编写出更具有通用性的程序。这种功能对于编写系统程序来说极其实用,但是通常不适于编写应用程序。反射是很脆弱的,即编译器很难帮助人们发现程序中的错误,因此只有在运行时才发现错误并导致异常。