Python中类和对象
Contents
编程分类
不同的编程语言,归根到底是一些逻辑代码结构构成的一个整体。当我们用这些逻辑代码去解决问题时,根据解决问题的方式不同可以分为:面向过程 和 面向对象。这两种方式的最大区别:看待问题问题的视角不同。
一开始读到 面向过程 和 面向对象 有点拗口。下面我就用两个简单的例子从 思维角度 来简单阐述两者的区别。
####面线过程思维
看过赵本山小品的应该对这个脑筋急转弯有印象吧。
Q:把大象放到冰箱里需要几步?
A:三步,1打开冰箱;2放入大象;3关上冰箱。
上面的脑筋急转弯其实就是典型的面向过程思维。面向过程思维:就是把一个问题逐步拆解,然后解决问题的方式。
####面向对象思维
在中学我们学习生物课的时候,我们接触过 生物分类 这个概念。根据生物之间的 亲缘关系 和 进化关系 可以用 界(Kingdom)、门(Phylum)、纲(Class)、目(Order)、科(Family)、属(Genus)、**种(Species)**7个层次对生物进行划分。
这种以某种 共同属性特征 而将一群 object(物体、客体、对象) 归为一类的方式就是面向对象思维。区分于面向过程,更注重的是一群object之间共有的属性。
下面就根据五子棋游戏的实现过程来详细讲解面向过程和面向对象的实现方式。
五子棋游戏实现
面向过程实现
根据前面介绍,面向过程注重的是:每一步做什么,及过程中的实现。所以对于五子棋游戏,可以把整个游戏的实现分为下面的过程:
- 开始游戏
- 黑子先走
- 绘制棋局画面
- 判断输赢
- 轮到白子走
- 绘制棋局画面
- 判断输赢
- 返回步骤2
- 输出结果
在上述的代码结构中,面向过程关注的是:一步一步地过程变化来判断棋局的输赢。
面向对象实现
在前面提到,面向对象思维是寻找不同object的共同点,对于五子棋游戏的实现又改如何着手呢?
如果细心的你,会发现我一直在打object这个单词。在现实生活中,我们可以用object来指代任一东西,如一本书、一棵树、一轮残月等等。这些在我们眼中就是真切存在的object,或者说客体、对象。
在计算机中,也有object概念。不管是指代一本书也好,或是一棵树也罢。object就是代表一个对象,一个可操作or可描述的对象。在计算机中我们可描述可操作的是什么呢?显然是一段代码、一个程序块。
所以这里我们讲到的 面向对象思维,就是把一类功能相近的代码块(object)放在一起,并采用生物学中 类(Class)统称这些代码。
其实 类(Class)就是一个更大的对象。
现在,我们看看通过面线过程实现五子棋功能的代码块。
- 步骤2黑棋走、步骤5白起走 是不是功能相近的代码块呢?所以可以用一个走棋系统 来实现。
- 同样,步骤3、步骤6 可以用一个 棋盘系统(负责绘制画面) 来实现。
- 步骤4、步骤7 可以用 规则系统(判断输赢) 来实现。
- 步骤1 可以称之为 启动系统。
- 步骤8 可以称之为 循环系统。
- 步骤9 可以称之为 结束系统。
当然,这只是我自己对代码功能做出的不同类型(Class)的区分。你也可以将步骤1和步骤9 归类为 起止系统。毕竟对代码块(object)进行功能上的区分本身就带着主观臆断。剩下的就是如何实现不同系统之间的协调配合了。
这里最重要的是理解:计算机中的代码块也可以采用生物学的分类概念来进行整合。 仔细理解计算机中object 和 Class的概念。
总结
既然实现五子棋的方式不同,那每种方法必定有其自身的特点。在给出面相过程和面向对象的优缺点比较之前,我再问一个问题:如何添加悔棋功能呢?
有人说直接加一个悔棋系统就好了,这是 面向对象 实现的方式。那面向过程如何实现呢?
下面看一个很形象的比喻,来感受一下二者之间的区别。
如果把面向过程比喻成蛋炒饭,那么面向对象就可以比喻为盖浇饭。
蛋炒饭:需要把鸡蛋、米饭、其他辅料(萝卜丁、肉丝等)一起下锅。所以入味均匀、吃起来香。如果你不爱吃蛋炒饭,或者不爱吃里面的一些辅料,唯一的办法就是重新换一份了!用计算机语言来讲就是:耦合度很高、不易修改。
盖浇饭:煮熟的米饭 + 做好的菜品。两者是分开做的,喜欢什么菜就在米饭上浇上一份自己喜欢的菜肴即可。如果不喜欢某一个菜式,直接换一份菜而不需把米饭也倒掉。但是入味就没有蛋炒饭香了,不过可选性高。用计算机语言来讲就是:耦合度很低、易修改。
好了,下面就给出二者优缺点的总结!
面向过程编程
单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
- 优点:
- 流程化使得编程任务明确、便于节点分析。
- 代码执行效率高。
- 缺点:
- 需要深入思考,耗费精力。
- 代码复用率低、扩展能力差。
- 不易于后期维护
面向对象编程
- 优点:
- 易维护、易复用、易扩展。
- 具有封装、继承、多态的特性。
- 代码之间耦合度低,更灵活。
- 缺点:
- 性能比面向过程低。
- 占用空间存储多。
面向对象编程的特性
面向对象编程有三大特性:封装、继承、多态。
封装
封装,就是把代码块封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
继承
继承,指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过 “继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用父类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。
多态
多态,是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。