返回介绍

OOP 是为了代码重用

发布于 2024-01-29 22:24:15 字数 2878 浏览 0 评论 0 收藏 0

这就是Python中OOP的大部分内容,此外,就是一些语法细节了。当然,除了继承之外,还有些其他的事。例如,运算符重载比这里所说的更为常见:类也可以提供自己实现的运算,例如,索引运算、取出属性和打印等。不过,大体而言,OOP就是在树中搜索属性。

那么,我们为什么对建立和搜索对象树感兴趣?虽然这得具备一些经验后才能了解的,但是妥善使用时,类所支持的代码重用的方式,是Python其他程序组件难以提供的。通过类,我们可以定制现有的软件来编写代码,而不是对现有代码进行在原处的修改,或者每个新项目都从头开始。

从基本的角度来说,类其实就是由函数和其他变量名所构成的包,很像模块。然而,我们从类得到的自动属性继承搜索,支持了软件的高层次的定制,而这是我们通过模块和函数做不到的。此外,类提供了自然的结构,让代码可以把逻辑和变量名区域化,这样也有助于程序的调试。

例如,因为方法只是有特殊第一参数的函数,我们可以把要处理的对象传给简单函数,来模拟其行为。不过,方法参与了类的继承,可让我们自然地通过新方法定义编写子类,通过这样定制现有的软件,而不需要对现有的代码进行在原处的修改。在模块及函数中是没有类似的概念的。

举个例子,假设任务是实现员工的数据库应用程序。作为一个Python OOP程序员,可能会先写个通用的超类,来定义组织中所有员工的默认的通用行为。

一旦你编写了这样的通用行为,就可以针对每个特定种类的员工进行定制,来体现各种不同类型和一般情况的差异。也就是说,可以编写子类,定制每个类型的员工中不同的行为。这个类型的员工的其他行为则会继承那个通用化的类。例如,如果工程师有独特的薪资计算规则(并非以小时计算),就可以在子类中只取代这一个方法。

因为这里的computeSalary版本在类树下面出现,所以会取代(覆盖)Employee中的通用版本。然后,你可以建立员工所属的员工类种类的实例,从而使其获得正确的行为:

注意我们可以对树中任何类创建实例,而不是只针对底端的类,创建的实例所用的类会决定其属性搜索从哪个层次开始。最后,这两个实例对象可能会嵌入到一个更大的容器对象中(例如,列表或另一个类的实例),利用本章开头所提到的组合概念,从而可以代表部门或公司。

当我们想查看这些员工的薪资时,可根据创建这个对象的类来计算,这也是基于继承搜索的原理[1]

这是第4章和第16章介绍过的多态概念的又一实例。回想一下,多态是指运算的意义取决于运算对象。在这里,computeSalary方法在调用前,会通过继承搜索在每个对象中找到。在其他应用中,多态可用于隐藏(封装)接口差异性。例如,处理数据流的程序可以写成预期有输入和输出方法的对象,而不关心那些方法实际在做的是什么。

把针对各种数据来源所需读取和写入方法接口定制的子类的实例传入后,都可以重用这个processor函数,无论什么时候都可以让它来处理所需使用的任何数据来源:

此外,因为读取和写入方法的内部实现已分解至某个独立的位置,修改这些代码是不会与正在使用的代码产生冲突的。实际上,processor函数本身也可以是类,让转换器的转换逻辑通过继承添加,并让读取器和写入器能够通过组合方式嵌入(稍后会说明如何实现)。

一旦习惯了使用这种方式进行程序设计(通过软件定制),你就会发现,当要写新程序时,很多工作早已做好。你的任务大部分就是把已实现的程序所需行为的现有超类混合起来。例如,某人已写好了这个例子中的Employee、Reader和Writer类,用在完全不同的程序中。如果是这样,你就可以“毫不费力”地采用那个人的所有代码。

事实上,在很多应用领域中,你可以取得或购买超类集合体,也就是所谓的软件框架(framework),把常见程序设计任务实现成类,可以让你在应用程序中混合。这些软件框架可能提供一些数据库接口、测试协议、GUI工具箱等。利用软件框架,只需编写子类,填入所需的一两个方法。树中较高位置的框架类会替你做绝大多数的工作。在OOP中写程序,所需要做的就是通过编写自己的子类,结合和定制已调试的代码。

当然,需要花点时间学习如何充分利用这些类,从而实现这种OOP是理想化。实际应用中,面向对象工作也需要有实质性的设计工作,来全面实现类的代码重用的优点。结果,程序员开始将常见的OOP结构归类,称为设计模式(design pattern),来协助解决设计中的问题。不过,在Python中所编写的用于OOP的实际代码是如此的简单,在探索OOP时不会增加额外的障碍。想了解原因,请继续学习第26章。

[1]注意,这个例子中的company列表可以使用Python对象的pickle功能(我们在第9章学习文件时介绍过)储存在文件中,以产生永久保存的员工数据库。Python有一个名为shelve的模块,可以把类实例的pickle形式储存在以键读取的文件系统内。第三方开源ZODB系统也是做的相同的事,只不过它对商业级面向对象数据库有着更好的支持。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文