面向对象程序设计的最强大的功能之一就是代码重用。结构化设计提供的代码重用非常受限。你可以编写一个功能块,然后多次重用它。但是面向对象的设计更进一步,允许你定义类之间的关系,通过组织和识别不同类之间的共性,不仅可以实现代码重用,也可以指导设计。继承是实现该功能的主要手段。
继承允许一个类继承另一个类的属性和方法。我们可以通过抽象公共属性和行为来创建新类。
面向对象程序设计中的一个主要设计问题就是识别多个类的共性。例如,假设你有一个dog(狗)类和一个cat(猫)类,这两个类都有一个属性来表示眼睛颜色。在过程化模型中,dog和cat的代码中都会包含这个属性。在面向对象的设计中,可以将颜色属性上移到一个名为mammal(哺乳动物)的类中。该类也会包含一些其他的公共属性和方法。在本例中,dog类和cat类都继承自mammal类,如图1-14所示。

当dog或cat对象被实例化时,它包含了自身类的所有东西,也包含了从父类获取到的东西。即dog拥有自身类定义的所有属性,也包含了从mammal类继承过来的属性。
超类,也称为父类(有时候也叫作基类),包含了继承自它的所有类的公共属性和行为。例如,在mammal类的例子中,所有的哺乳动物拥有相似的属性,比如eyecolor和haircolor,也有相似的行为,比如generateinternalheat和growhair。所有的哺乳动物都有这样的属性和行为,所以没必要在哺乳动物继承树中为每个动物中都重复一遍。重复不仅加重工作量,而且会带来更多问题,因为会引入错误和矛盾。
子类,也称为孩子类(有时被叫作衍生类),是超类的扩展。比如,dog和cat类从mammal类继承了所有的公共属性和行为。mammal类是dog和cat子类的超类。
继承提供了丰富的设计优势。当设计cat类时,mammal类提供了很多需要的功能。通过继承自mammal对象,cat已经拥有了成为真正的哺乳动物的所有属性和行为。为了让猫这种哺乳动物更加具体,cat类必须拥有猫自身独一无二的属性或行为。
继承树可能会增长的非常庞大。当mammal和cat类完成后,可以快速添加其他哺乳动物,比如狗(或者狮子、老虎和熊)。cat类也可以作为其他类的父类,比如作为塔罗猫等猫的父类。而dog类也可以作为germanshepherd(德国牧羊犬)和poodle(卷毛小狗)的父类(见图1-15)。继承的力量在于它的抽象和组织技术。
在大多数最新的面向对象的语言中(比如java、.net和objective c),一个类只能有一个父类,然而一个类可以有多个子类。另一些语言中,比如c++,可以拥有多个父类。前一种情况称为单继承,后一种情况称为多重继承。
请注意germanshepherd类和poodle类都继承自dog类。每个类只有一个方法。然而由于它们继承自dog,所以它们也继承自mammal。即germanshepherd和poodle类获取了dog和mammal中所有的属性和方法,同时也拥有它们自身的属性和方法(如图1-16所示)。
在shape(形状)例子中,circle(圆形)、square(矩形)和star(星形)都直接继承自shape。这种关系通常被称为is-a关系,因为圆是一个形状,而矩形也是形状。当子类继承自父类时,任何父类能做的事情子类都可以做。即circle、square和star都是shape的扩展。
在图1-17中,每个对象上的名字draw分别代表了circle、star和square对象的draw方法。当我们设计shape系统时,采用这种方式对各种各样的形状进行标准化。这种方式非常有用,如果我们约定绘制形状时只需调用draw方法即可,而不用管具体是什么形状。那么只要遵守这一约定,无论什么时候绘制形状,只需调用draw方法即可。这正好展示了多态的基本概念,即绘制circle、star或square是各自对象自身的职责。在如今很多软件应用(比如在绘图和文字处理应用)中都会使用多态概念。