一、面向过程和面向对象的区别
面向对象(Object Oriented,简称OO)和面向过程(Procedure Oriented,简称PO)是两种不同的编程思想。
1.1 面向过程的编程
面向过程编程(Process Oriented Programming,简称POP),以事物的发展过程为中心的编程思想,它根据流程一步一步解决问题。
1.1.1 面向过程的程序设计
传统的面向过程程序设计是围绕功能进行的,用一个函数实现一个功能。面向过程的程序设计具备如下特点:
a. 程序按要解决的问题划分为各个小程序,这些小程序被称为函数;
b. 大多数函数共享全局数据;
c. 数据是开放的,由一个函数流向另一个函数。函数把数据从一种形式转换为另一种形式。
1.1.2 面向过程编程的优缺点
面向过程编程的优点就是其性能比面向对象高,因为面向对象编程的对象调用时需要将对象实例化,开销大。面向过程编程消耗资源少,性能高。但面向过程编程存在很大的缺点。
a. 代码维护难度大在多函数程序中,许多重要的数据被声明为全局变量,这样它们才可以被所有的函数访问。每个函数又可以有自己的局部变量。全局变量很容易被某个函数不经意之间改变。而在一个大程序中,很难分辨每个函数都使用了哪些变量。如果我们需要修改某个外部数据的结构,我们就要修改所有访问这个数据的函数。这样很容易导致bug的产生。
b. 不能很好的模拟真实世界的问题。
函数都是面向过程的,而不是真正的对应于问题中的各个元素。总的来说,相较于面向对象编程,面向过程编程性能好,但是代码维护难度大、程序很难复用和扩展。
1.2 面向对象的编程
面向对象编程(Object Oriented Programming,简称OOP),能很好的模拟真实世界的问题,能真正的对应于问题中的各个元素。
1.2.1 面向对象的程序设计面向对象的程序设计思路和日常生活处理问题的思路是类似的。在自然世界和社会生活中,一个复杂的事物总是由许多部分组成。譬如手机的生产,需要分别设计屏幕、电池、芯片、摄像头等,最后将它们组装在一起。在组装的时候,各部分零部件有一定的联系,以便协调工作。这就是面向对象的程序设计的基本思路。
1.2.2 与面向对象有关的几个概念
a. 对象
客观世界中任何一个事物都可以看成一个对象(object),它是程序中的基本单元。一个对象具备两个要素:属性(attribute)和行为(behavior)。若使这个对象实现这个行为,需要其他对象向其传送相应的消息,这样对象之间就通过发送和接收消息取得联系。如图1所示,在Go语言中,每个对象都是由数据和操作这些数据的方法构成的。对象中的数据体现了“属性”要素。例如一个圆形对象,数据半径是它的属性,方法是对该对象中的数据进行的操作。如果要实现这个对象计算面积的功能,就可以通过方法对数据的半径进行操作,实现计算该对象面积这个行为。
b. 封装与信息隐蔽
封装是面向对象三大基本特性之一,它包含两方面含义:
一是将有关数据和操作数据的方法封装在一个对象中,形成一个基本单元,各对象之间相对独立,互不干扰。二是将对象中某些部分对外隐蔽,即隐蔽其内部细节,只留下少量跟外界联系的渠道,以便接收外界的消息。这种对外界隐蔽的做法称为信息隐蔽(imformation hiding)。它有利于数据安全,防止无关的人了解和修改数据。在Go语言中,通过方法将数据和操作这些数据的方法封装在一个对象。方法这个概念在后续章节再做介绍。
c. 抽象
抽象是将有关事物和对象进行共性归纳和集中,它表示同一类事物的本质。类是对象的抽象,对象是类的特例,也就是类的具体形式。Go语言通过结构体(struct)将有关事物和对象进行共性归纳和集中。
d. 继承与重用
如果在软件开发中已经建立了一个名为A的“类”,又想另外建立一个名为B的“类”,而后者与前者内容基本相同,只是在前者的基础上增加了一些属性和行为,只需在类A的基础上增加一些新内容即可。这就是面向对象程序设计的继承机制。利用继承可以简化程序设计的步骤。例如,“白马”继承了“马”的基本特征,又增加了新的特征——颜色。“马”是父类,或称为基类;“白马”是从“马”派生出来的,称为子类或派生类。Go语言没有“继承”这个概念,但它通过匿名组合实现了这个功能,这就是“软件重用”(software reusability) 的思想。匿名组合在后续章节再做解释。
e. 多态性
一千个读者就有一千个哈姆雷特。面对同一事物,或者同一个消息,不同的人会有不同的表现,这种情况就是多态。在Go语言中,没有多态这个概念,但Go语言通过接口(interface)实现了多态,我们在后续章节还会重点介绍接口。接口存储了一系列的方法,虽然不同类型的对象实例可以调用同一接口,即调用的都是相同方法名的方法。但是由于建立在不同类型的方法内容不同,它的表现形式就不相同。
1.2.2 面向对象编程的优缺点
面向对象编程由于对象实例化消耗资源,性能比面向过程低。但面向对象编程的优点很多:
a. 代码维护简单
把事物看成对象,将数据和操作数据的方法进行封装,对象之间相互独立。这样在代码维护就更加简单。
b. 信息安全
将对象中的一些信息对外界隐藏,数据更加安全。
c. 可扩充性
面向对象编程通过继承可以很快地扩充这个类,创建一个具有扩充的功能的类。系统很容易从小到大逐步升级。
d. 表现灵活
不同的对象实现同一接口,有不同的表现形式。
二、Go语言的面向对象编程
Go语言在面向对象编程的设计简洁又优雅。Go语言简洁,这是因为Go语言没有沿袭传统面向对象编程中的诸多概念,比如封装、继承、多态、虚函数、构造函数和析构函数、隐藏的this指针等。Go语言优雅,这是因为Go语言对面向对象的支持是语言类型系统中的天然组成部分。封装、继承、多态是面向对象的三大特性。尽管Go语言没有封装、继承、多态这些概念,但它通过以下方式实现了这些特性:▷封装:通过方法实现(方法在后续章节分析);
▷ 继承:通过匿名组合实现(匿名组合在后续章节分析);
▷ 多态:通过接口实现(接口在后续章节分析)。参考资料
[1] 谭浩强.C++面向对象程序设计[M]. 清华大学出版社,2006
[2] 陈维兴,陈昕.C++面向对象程序设计[M]. 人民邮电出版社,2010