前言:继承是Java中的一项核心技术,何时设计继承,该如何设计继承,本文记录一点继承的设计技巧。

1、将公共操作和域放在超类

如标题所表述的意思,在考虑设计继承时,尽可能地将一些公共的域或方法放在超类中。

2、不要使用受保护的域

将大多数的实例域定义为protected,以使子类在需要的时候可以直接访问,看起来是一个不错的设计。然而,protected机制并不能带来更好的保护,其主要原因有两点:

(1)子类集合是无限制的,任何一个人都能由某个类派生出一个子类,并编写代码以直接访问protected实例域,从而破坏了封装性。

(2)在Java中,同一个包中的所有类都可以访问protected域,而不管它是否为这个类的子类。

虽然有以上两点,但protected方法对于不提供一般用途而应在子类中重新定义的方法很有用。

3、使用继承实现“is-a”关系

使用继承很容易达到节省代码的目的,但使用时要注意继承关系和结构层次的设计,避免因不恰当的继承,导致更多的麻烦。

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

5、在覆盖方法时,不要改变预期的行为

置换法则不仅应用于语法,也可以应用于行为,这似乎更重要。在覆盖一个方法时,需注意的一点是,不应该毫无缘由地改变行为的内涵。关于这一点,无法从编译器获得任何帮助,编译器不会检查重新定义的方法是否有意义。因此,需慎重思考覆盖方法是否有意义。

6、使用多态,而非类型信息

任何时候都应该考虑对下面形式的代码考虑使用多态性:

if(x is oftype1)
    action1(x);
else if(x is oftype2)
    action2(x);

思考一下,action1和action2是否是相同的概念?如果是,应该为这个概念定义一个方法,并放置在两个类的超类或接口中,如此,便可调用

x.action();

如此,使用多态性提供的动态分派机制执行相应的动作。

使用多态方法或接口,比使用多种类型检测代码更易维护和扩展。

7、不要过多地使用反射

反射可以在运行时查看域和方法,可以编写出更具通用性的程序,对于编写系统程序及其实用,但不适于编写应用程序。反射及其脆弱,编译器很难帮助发现程序中的错误,很容易导致运行时异常。