有时候,继承只应该重写基类方法(不添加基类中没有的新方法),这将意味着派生类完全是同一类的基类,因为它有完全相同的接口。在这种情况下,完全可以用基类的对象替换派生类的对象。这可以被认为是纯粹的替代,通常被称为替代原则。从这个意义上说,这是对待继承的理想方法。这就是is-a关系,比如说,“圆是一种形状(A circle is a shape)”。
有时,必须将新的接口元素添加到派生类型,从而扩展接口。新的类型仍然可以被替换为基类,但替换并不是完美的,因为你的新方法是不可从基类访问的。这可以被描述为一个is-like-a关系。新类型拥有旧类型的接口,但它也包含其他的方法,所以你不能真的说它是完全相同的。例如,考虑一个空调(见图3-10)。假设你的房子与所有的冷却控制连接,也就是说,它有一个接口,允许你控制冷却。想象一下,空调坏了,你用一个热泵替换它,它可以加热和冷却。热泵像一个空调,但它可以做更多。因为你的房子的控制系统设计只是为了控制冷却,它被限制在只能与新的对象的冷却部分通信。新对象的接口已扩展,但现有的系统不知道除了原始接口以外的任何事情。
图3-10 一个例子
当然,一旦你看到这个设计,就很清楚,基本的“冷却系统(cooling system)”是不够的,应该重新命名为“温度控制系统(temperature control system)”,这样也可以包括加热。