一个小白眼中的“面向对象”

《Head First Java》是我学习计算机以来第一本坚持读下来的书,也是我见过的最有趣的编程语言教程。
不同于其他的书,这本书,或者说整个《Head First》系列,最大的不同之处,在于它们写的根本不像教程,而像小说…让读者可以在愉快的氛围中,不经意间就能明白很多课堂上老师怎么“填鸭”也填不懂的概念。

本文是一个小白眼中的面向对象。

作为某不知名院校的本科大学生,对于大学的计算机学习颇有感悟,
对于非计算机专业的学生来说,我们唯一一门计算机课就是《VC程序设计》,表面上是C++,实际就是C,因为不涉及任何类和对象的知识,完全就是面向过程。学习的内容,仅仅是输入输出、数据类型、简单的循环和判断罢了…学习的效果呢,大多数学生记得最最最深刻的就是:

#include<iostream>
using namespace std;
int main(){
    return 0;
}

然后写什么来着…不知道了…
就是这个水平!
《一个小白眼中的“面向对象”》

所以,和许多大学生一样,在学习Java之前根本不知道什么是面向对象,脑子里的思维也都是面向过程。

一、面向过程

首先,面向过程是什么呢?
过程”,一想到这两个词,我大脑中的第一反应就是加工厂、生产流水线,也可以理解成数学中的函数。

“生产一杯咖啡需要怎么做?”
需要水和咖啡粉作为原料,先把水烧热,然后倒入咖啡粉中就实现了。那么我们可以画这样一张图。
《一个小白眼中的“面向对象”》

“过程”就是一个流水线,在面向过程设计程序的时候,我们只需要考虑,从输入到输出是怎样实现的,经历了怎样的步骤,然后把这个实现方式拆分成一个一个的具体步骤,在程序运行时按顺序去执行就可以了。于是面向过程就可以抽象成下图:
《一个小白眼中的“面向对象”》

面向过程中,所有的数据都是用变量来储存的,所有的步骤都是通过函数来实现的。
在面向过程时,大脑里面所想的都是流程,也就是工厂的每一道工序。

二、面向对象闪亮登场

那么面向对象有什么区别呢?

面向对象的思维,或许更接近与实际生活。
当我自己尝试去理解对象时,我的大脑中呈现出的,不再是一个加工厂,而是一个生机盎然的公园,公园中有许多人和各种各样的小动物,孩子们在嬉戏玩耍,蜜蜂在花丛中采蜜,旁边还有一位作家坐在石凳上正准备打开电脑写文稿…

这副画面中,一个孩子、一只蜜蜂、一朵花、一位作家、以及它手中的电脑,一切的一切,都是对象
而在这些对象之间,正在通过某种方法,发生着相互影响。
所以,面向对象和面向过程最大的不同是,面向对象不再去关注完成某件事情需要怎样的步骤,而是更加注重事物之间发生着怎样的联系

对象包含两个重要的内容:一个是对象的属性、另一个则是对象的方法
以刚才说到的作家手里的笔记本来举例:一台笔记本,必然有一个状态——开机或关机,那么它的状态就是一个属性;笔记本还有内存大小、硬盘容量、CPU型号等等等,这些也都是这台笔记本的属性。

简单来讲:对象的“属性”,就是在面向过程中提到的“变量”

“方法”又是什么呢?现实生活中,一个方法其实就是要实现一个功能,比如笔记本的“开机”方法,就是把这台笔记本的状态从关闭变成打开,那么“开机”就是这台笔记本的一个方法;笔记本还可以打开文档,并且显示出文档的内容,那么“打印文档信息”就是这台笔记本的另一个方法,并且这个方法有输出值,就是文档信息的字符串。
那么到底对象的“方法”要怎么去解释呢?——可以理解成面向过程中提到的“函数”。

《一个小白眼中的“面向对象”》

但这并不严谨,或者说不完全正确,因为变量只是为了客观储存数据,而属性虽然也可以储存数据,但它是对象的一种特征变量可以脱离对象而存在,但属性不可以,如果没有对象,属性就失去了意义(如果没有电脑这个实体,你能想象“开机”是一个什么样的状态吗?)。
同理,函数表示一种数据处理的过程,而方法表示此对象和其他对象发生联系的一种方式,方法也是不能脱离对象而存在的(如果让一个从未见过电脑的人去关掉电脑,那也是很为难他呢!)。

《一个小白眼中的“面向对象”》

三、类

我们继续拿笔记本电脑来举例,小强、小达和小轩都有自己的笔记本电脑,而这些电脑都有共同的特点,所以就可以说,他们属于同一个“类”。

“类”是什么?
生活中的类是什么呢?用通俗的语言说就是一羣有着共同特点的东西。所以类就是有着共同属性和方法的一羣对象的模板、蓝图。如果几个对象属于同一个类,那么这个类就含有这些对象共有的属性和方法。并且,可以从这个类里面再创建新的对象,新创建的对象同样有这个类的特点。

或许初次接触类和对象时,我们感受不到它有什么用。我们继续说,如果需要用变量来表示小强、小达和小轩三个人的电脑的信息,应该怎么做呢?

假设,每一台笔记本有三个信息:磁盘容量、内存大小、开关机状态。

如果在面向过程的思维中,是这样的:

//小强的笔记本
int XiaoQiang_Disk;
int XiaoQiang_Memory;
bool XiaoQiang_Status;

//小达的笔记本
int XiaoDa_Disk;
int XiaoDa_Memory;
bool XiaoDa_Status;

//小轩的笔记本
int XiaoXuan_Disk;
int XiaoXuan_Memory;
bool XiaoXurn_Status;

需要定义 3 * 3 = 9 个变量。

如果是面向对象呢?

//定义一个笔记本类
class laptop{
    int disk;
    int memory;
    bool status;
}

//基于这个类创建三个对象
laptop XiaoQiang = new laptop();
laptop XiaoDa = new laptop();
laptop XiaoXuan = new laptop();
    

需要定义 3 + 3 = 6 个变量。

或许这也不要紧,不就是少写了几个变量嘛?可是试想,如果需要表示的笔记本增加到10000个呢?
在面向过程的世界中,需要定义 10000 * 3 = 30000个变量;而使用面向对象的思维,只需要定义10000 + 3 = 10003个变量。

准确的讲,如果通过某个类来新建一个对象,这个对象就会把这个类的所有非静态属性和非静态方法复制一份,只要新建了这个对象,就相当于一次性把这个类的所有属性都新建了一次。因此,面向对象有一个最简单的好处,就是把本来需要新建指数个变量才能表示的信息,变成只需要新建线性级别的变量就能表示了。

四、继承

面向对象的另一个好处就是继承。
“继承”这个词用的十分形象,让人可以瞬间想到生活中父母把自己的财物交给儿女,儿女接受财产的这个动作就是继承,继承也可以说是“下一代”从“上一代”的手中获取了一些东西。“获取”的究竟是什么呢?——属性和方法

被继承的类叫做父类(给东西的类),执行继承的类叫做子类(索取东西的类)。继承这个动作可以理解成“以类为模板,又新建了一个类”,从意义上说,子类是父类的具体化。

还是说计算机,计算机分为很多种:PC机、笔记本、服务器…他们都是计算机,有许多共有特点,都有磁盘、内存、CPU…所以可以建立一个“计算机”类,表示所有计算机的模板。然而它们又有各自的特点,所有的笔记本都有电池,所有的服务器都有ECC校验内存,所有的PC都有显示器…所以,可以基于三者的特点分别建立这三个类,都从“计算机”类继承,这样他们既保留了公共属性又有自己的特点。

《一个小白眼中的“面向对象”》

五、多态和接口

还有更厉害的——那就是多态和接口…由于目前能力有限,因此留到下次再写。

六、总结

在我这个小白看来,面向对象比面向过程更贴近实际生活,因为一个对象可以是生活中的实物,所以只需要把这些物品的共有属性抽象出来,就是一个类。面向对象的思维更容易去理解,也有许多优势(继承、接口、多态…)。

去年,在我初学计算机时,上来就被“面向过程”和“面向对象”这两个词给搞懵了,老师讲课时的解释模棱两可,导致我根本不明白老师在说什么,后来查了一些帖子,发现他们说的也不是很清楚…直到现在学习了PHP和Java,真正的做过了项目,才对这两个词语有了较深的理解。对于上述概念如果有表达错误或者不准去的地方,欢迎指出。

点赞