编程范式与 OOP 引入¶
约 1009 个字 88 行代码 预计阅读时间 4 分钟
编程范式¶
编程范式说明了编程语言的不同特点;分类依据包括语言的代码组织方式、运行时模型、语法风格等。我们提到的 OOP,就是按照「代码组织方式」分类的一种编程语言的特点。
那么什么是 按代码组织方式分类 呢?
非结构化编程语言¶
在汇编语言中,不存在诸如分支、循环之类的语言结构,他们都是用比较和跳转的指令组合来完成相应效果的。
早期的 BASIC 等语言即使存在类似含义的关键字,但是仍需要 jmp
或者 goto
等含义类似的语句来完成:
对比之下,C++ 就是以语句块为单位:
(上面这个代码中,3~7 行是一个完整的语句)
从非结构化到结构化,我们把计算机具体的、与机器和环境高度相关的指令抽象成了更接近人类思维的指令,牺牲了精密的可控性,提高了通用性、易读写性和可移植性。
Object-Oriented Programming¶
OOP 是一种编程范式,强调封装、继承和多态。
封装(Encapsulation)¶
对比 C 语言,从思想方面,我们希望将数据和操纵数据的函数更加明显地捆绑在一起;从语法上来说,我们扩展了 struct,现在 struct 不仅可以包含成员变量,还能包含成员函数:
线性表(链表实现)
线性表(数组实现)
对象和类¶
从编程的角度来看,状态可以用数据变量表示,行为可以用函数表示。
类是一种用户自定义的数据类型,程序员可以创建这种类型的变量(对象 / 实例(instance)),并且进行操纵。这种数据类型是状态和行为的集合,即用变量和函数来描述并且定义。这些变量和函数,是这个类的成员。
在 C 这种非 OOP 的语言中,用户自定义的类型只能定义状态而不能定义行为,这种思想更贴近机器实现——真正的汇编代码确实不能有同名的函数。但是 OOP 在此基础上做了进一步的抽象,让代码更加贴近人们对类自然的理解,机器层面的实现则交给编译器。
访问控制¶
在 C++ 中,提供了 access-specifier 来解决“类中成员变量对外权限”的问题,包括 public
, private
和 protected
三种,我们主要只讨论前两种。
所谓 public
,是说这之后的成员变量和成员函数对外部可见;而 private
则是说这之后的成员变量和成员函数不能在类外被访问,只能在类的成员函数内访问或调用。例如:
此时,如果外部代码尝试访问 private 变量,就会被编译器拒绝,在这种情况下,private 的变量在外部只能通过 checkPassword
,setAge
,getAge
这些函数间接访问,从而让外部的访问是有限制并且经过检查的。
(在 C++ 中,struct 默认都是 public,class 默认都是 private,其余二者没有任何区别)
继承 & 多态(Inheritance & Polymorphism)¶
考虑如果我们有很多个极其相似的类,如果我们要对他们进行集体改动、集体操作怎么办?
一个很自然的想法是对于这些相似的类定义一个更加高级的类,记录那些共同的部分,然后在定义低级的类时,对高级类的成员和行为进行继承。
比如我们先定义一个“图形类”:
基于这个图形类,我们再定义具体的 Circle 和 Rectangle:
在 Shape 中,虽然 do_draw()
是一个函数,但是在代码运行的时候,会更具调用它对象的实际类型来决定到底调用 Circle::do_draw()
还是 Rectangle::do_draw()
。这种机制就是 OOP 中的 多态 (polymorphism)。