前言

面向对象编程是我们接触编程过程中很早就接触到的概念。还记得刚上大学的时候,老师给我们讲了面向对象的三个特性封装、继承、多态,并实际用代码展示了他们的外在表现形式。后来就是代码实操了,再往后,工作一年半多了才真正意义上想要去了解这一思想,开始恶补面向对象编程思想、设计模式等等。接下来是我自己的面向对象这一思想的浅谈,供其他人参考。

什么是面向对象编程

首先我引用一句别人说过的话:“程序的一切功能,都是调用加封装的结果。”调用什么呢?调用的是对象;封装什么呢?封装的也是对象。无论早期的编程还是现在的编程,都是围绕对象来编程的。

接下来我们来说说面向对象的发展史。以时间顺序,按照大类来分,可以分为汇编语言->C语言->其他语言(PHP、C++、Java等)。上面我们说到,我们是围绕对象来编程的,但是对象的界定方式又有所不同,比如我们可以说人是由身体和灵魂构成的,也可以说人是由头、躯干、四肢构成的,角度不同,对事物的定界定也不同。我们再回头看发展史,其实就是由面向计算机视角的编程转变为面向人视角的编程的发展过程。

一开始的时候,对象是在计算机视角定义的,在机器眼中CPU上的电路、内存上的电路就是一个个对象,我们通常说的机器指令就是这些电路,我们用一串二进制的数来表示这些指令,也就是说在机器眼中这一串数就是对象,所以机器调用和封装的就是像这样比较底层的对象。汇编语言就是用单词代表这些二进制的数,从本质上看换汤不换药,这也是汇编语言一直健在的原因;后来C语言出世,它不是在机器的视角界定的对象,也不是从人的视角界定的对象,在它的眼中,对象就是数据和算法,这对人们来说,要比汇编语言直观的多,但C语言的底层还是机器语言,只不过把机器语言进行来封装,用C语言的语法来封装和调度;讲到这里,我们可以看出,C语言其实还是偏向计算机视角来界定对象,人们当然希望能够完全从人的视角去界定对象,而完全从人的视角界定对象的编程就是我们通常说的面向对象编程。我们把数据和算法结合起来,就是面向对象编程的对象,可以看到在C语言中,数据和算法是分开的。

为什么要采用面向对象编程

很简单,解决问题更容易,毕竟设计计算机程序就是为了解决人类的问题。这里有个叫做“动态编程”的过程,这是一个将大问题,拆分成一个个小问题的技术。其策略就是先解决这些小问题,然后把所有结果汇总起来形成一个更大的解决方案。有点类似工厂里面的流水线,先把各个小部件制造出来,最后加工组合成一个完整的产品。

拆分小问题的过程就是模块化。

类和对象

我们把一个问题模块化后,该怎么处理这些模块呢?我们常用的做法就是把一个模块看作是相关函数的一个集合。在编程中,我们把这些模块称为类,类又两部分组成,属性和方法。属性就是不同类型的数据对象,比如数字,字符串,null。通常数据作为抽象数据类型存储,比如存储为变量、常量、数组;方法就是处理这些数据的函数。

抽象

我们在谈到面向对象的三大特性之前,需要先了解抽象。

什么是抽象?OOP和设计模式的先驱给了一个明确的定义:“抽象指示一个对象的基本特征,使它与所有其他对象区分开,从而从查看者的角度提供了清晰定义的概念边界。”简单说就是对对象进行分组和分类,比如忠实的,毛茸茸的、摇尾巴的、爱舔来舔去的、湿鼻子的我们称之为狗,狗就是一个对具体的相似性的抽象。

除了常规的类,PHP提供了抽象类。抽象类不能实例化,只能由具体类继承抽象类的接口及它的所有具体属性。其实很好理解,抽象类就相当于提出了定义狗的特征,我们在它的基础上进行判断,金毛是狗,哈士奇是狗,但不能说狗是什么,狗是一个概念,不是具体指某个动物,而是某类动物。

如果一个类至少有一个抽象方法,它必然是一个抽象类。上面我们说过,函数就是方法,要写一个抽象函数,可以用abstract关键字来声明,它可以只包含接口,不包括其他任何内容,如:

1
abstract public function test($number);

如果一个抽象类声明来一个抽象方法,那么继承这个父类的各个子类都必须实现这个方法。

封装

说到封装,可能大家都不陌生,我用现实的例子可能更好理解这一概念。就像是一辆汽车,它由很多对象构成,发动机、内燃机、电力系统等等,可是我们需要都了解吗?我们要启动车只需要打火就可以了,并不需要了解在你打火时汽车都做了什么,这就是封装。车子打火后就能启动,你并不知道它具体做了哪些事情,这就是信息隐藏。

通过可见性保护封装。为什么要保护封装?比如你正常开车行驶,有一辆车接近你,你开着窗,他伸手抢你的方向盘,这就影响了你的开车,我们称之为破坏封装,所以我们需要摇起车窗,来保护我们的“封装”不被破坏。回到正题,可见性是指对类属性的存取或访问。PHP有三种可见性:private(私有)、protected(受保护)、public(公共)。

私有,就是说明这个属性只能在同一类中使用,它仅对这个类中的元素可见,继承它的类或者其他类都不能读取。

受保护,就是说明这个属性只能在同一类或者继承它的类中读取,对其他类不可操作。 公共,顾名思义,就是说明大家都可以读取。

要封装一个程序元素,最好的方法是设置为私有,但是要访问封装对象,必须提供公共可见性,总不能用车的时候,连打火都不让吧。

继承

继承是一个简单的概念,一个类如果拓展类另外一个类,就会拥有这个类的所有属性和方法。被继承的类叫做父类,继承了其他类的新类叫做子类。举个例子:有个父类中有个test函数,子类中就可以调用这个test函数,如果不满意父类中test函数实现的功能,修改类部分代码,这就叫做重写。

当然,你可以在继承父类的基础上调用父类的方法,同样也可以写新的方法。

多态

多态就是指多种形态。它的基础是继承,也就是说要实现多态,就必然涉及到继承。那么,怎么去理解多态呢?

举个例子,我们声明了一个名为dog的接口,定义了一个叫name的函数。一个类继承了这个接口,name函数返回了哈士奇,另外一个类也继承了这个接口,返回了金毛。同一个函数,返回了不同的名字,这就是多态。

后记

面向对象编程这一思想,并不是一下就能理解的,它需要我们花时间和精力去慢慢了解,上面讲述的只是一些简单的概念,在今后的学习中相信我们将能更深刻理解。