1. 将公共操作和域放在超类
例如Employee类和Student类继承自Person类,但将姓名域放在Person类,而不是2个子类。
2. 不要使用受保护的域
protected机制不能很好保护这些域,因为:
1)子类继承无限制,派生类可以在代码中直接访问protected域,破坏封装性;
2)Java中,同一个包中的类都可以访问protected域,而不管它是不是这个类的子类;
不过,protected针对指示不提供一般用途而应在子类中重新定义的方法很有用。
3. 使用继承实现“is-a”的关系
使用继承容易节省代码,不过也容易被滥用。假设需要定义一个钟点工类Contractor,包含姓名、雇佣日期,不过没有薪水,按小时计薪,不会加薪或者减薪。
如果雇员Employee派生出Contractor,为钟点工添加一个hourlyWage域代表按小时计薪。不过,这样也意味着钟点工也包含了计薪和薪水2个域,在实现打印账单或者税单的时候,容易产生混乱。与其这样,还不如不要使用继承。
钟点工与雇员不是“is-a”的关系,无需使用继承。
4. 除非所有的继承方法都有意义,否则不要使用继承
5. 在覆盖方法时,不要改变预期的行为
编译器不会检查重新定义的方法是否有意义,这点需要靠设计者自行遵守。比如,继承Stack实现一个自定义栈的add方法,修改功能为删除元素,remove为添加元素,这样并不符合父类定义的方法的预期行为,甚至完全相反。
6. 使用多态,而非类型信息
例如,
if (x is type1)
action1(x);
else if (x is type2)
action2(x);
如果action1和action2是相同概念,可以将方法放到一个公共的超类或者接口中,然后用一条语句调用。充分利用多态方法和接口编程。
x.action(); // 使用多态性提供的动态分派机制执行相应的动作,具体执行哪个类的action方法,取决于实例x所属的类
7. 不要过多地使用反射
反射能让人编写通用程序,适合用来做库和框架系统程序、工具等,但不适合用来编写应用程序。