设为首页 加入收藏

TOP

1.5 继承:重用接口
2013-10-07 14:16:00 来源: 作者: 【 】 浏览:62
Tags:1.5 继承 重用 接口

1.5   继承:重用接口

对象的思想本身是一种很方便的工具。它允许我们将数据和功能通过概念封装在一起,使得我们能描述合适的问题空间思想,而不是被强制使用底层机器的用语。通过使用class关键字,这些概念被表示为程序设计语言中的基本单元。

然而,克服许多困难去创造一个类,并随后强制性地创造一个有类似功能的全新的类,似乎并不是一种很好的方法。如果能选取已存在的类,克隆它,然后对这个克隆增加和修改,则是再好不过的事。这是继承(inheritance)带来的好处,例外的情况是,如果原来的类(称为基类、超类或父类)被修改,则这个修改过的“克隆”(称为派生类、继承类或子类)也会表现出这些改变。

 

(在上面的UML图中,箭头从派生类指向基类。正如你将会看到的,可以有多个派生类。)

类型不仅仅描述一组对象上的约束,而且还描述与其他类型之间的关系。两个类型可以有共同的特性和行为,但是一个类型可以包括比另一个类型更多的特性,也可以处理更多的消息(或对消息进行不同的处理)。继承表示了在基类型和派生类型之间的这种相似性。一个基类型具有所有由它派生出来的类型所共有的特性和行为。程序员创建一个基类型以描述关于系统中的一些对象的思想核心。由这个基类型,我们可以派生出其他类型来表述实现该核心的不同途径。

例如,垃圾再生机器要对垃圾进行分类。这里基类型是“垃圾”,每件垃圾有重量、价值等,并且可以被破碎、被融化或被分解。这样,可以派生出更特殊的垃圾类型,它们可以有另外的特性(瓶子有颜色)或行为(铝可以被压碎,钢可以带有磁性)。另外,有些行为可以不同(纸的价值取决于它的种类和情况)。使用继承,我们可以建立类型的层次结构,在该层次结构中用其类型术语来表述我们需要解决的问题。

第二个例子是经典的“形体”范例,可以用于计算机辅助设计系统或游戏模拟。在这里,基类型是“形体”,每个形体有大小、颜色、位置等。每个形体能被绘制、擦除、移动、着色等。由此,可以派生出特殊类型的形体:圆形、正方形、三角形等,它们中的每一个都有另外的特性和行为。例如,某些形体可以翻转。有些行为可以不同,形体面积的计算。类型层次结构既体现了形体之间的相似性,又体现了它们之间的区别。

 

用与问题相同的术语描述问题的解是非常有益的,因为这样我们就无须在问题的描述和解的描述之间使用许多的中间模型。使用对象,类的层次结构就是最初的模型,所以能直接从实际世界中的系统描述进入代码中的系统描述。实际上,使用面向对象设计,人们的困难之一是从开始到结束过于简单。一个已经习惯于寻找复杂解的训练有素的头脑,往往会被问题本来的简单性所难住。

当我们从已经存在的类型来继承时,我们就创造了一个新类型。这个新类型不仅包含那个已经存在的类型的所有成员(虽然私有成员已被隐藏且不可访问),但更重要的是,它复制了这个基类的接口。也就是说,所有能够发送给这个基类对象的消息,也能够发送给这个派生类的对象。因为我们能够根据发送给一个类的消息知道这个类的类型,所以这意味着这个派生类与这个基类是相同类型的。在前面的例子中,“圆形是一个形体”。这种通过继承实现类型等价性,是理解面向对象程序设计含义的基本途径之一。

由于基类和派生类有相同接口,因此伴随着接口必然有一些实现。也就是说,当对象接收到一个特定的消息后必定执行一些代码。如果只是简单地继承一个类,而不做其他任何事情,来自基类接口的方法也就直接进入了派生类。这就意味着,派生类的对象不仅有相同的类型,而且有相同的行为,这一点并不是特别有意义的。

有两种方法能使新派生类区别于原始基类。第一种相当直接,简单地向派生类添加全新的函数。这些新函数不是基类接口的一部分。这意味着,这个基类不能做我们希望它做的事情,所以必须添加函数。继承的这种简单和原始的运用有时就是问题的完美解。但是,我们会进一步看到,基类可能也需要这些添加的函数。在面向对象程序设计中,这种设计的发现和迭代过程会经常发生。

 
虽然继承有时意味着向接口添加新函数,但这未必真的需要。使新类有别于基类的第二个和更重要的方法是,改变已经存在的基类函数的行为,这称为重载(overriding)这个函数。
 
要覆盖函数,可以直接在派生类中创建新定义。相当于说:“我正在使用同一个接口函数,但是我希望它为我的新类型做不同的事情。”


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.2 对象有一个接口 下一篇1.2.3 C++的应用领域

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: