零
《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,真正的做过了项目,才对这两个词语有了较深的理解。对于上述概念如果有表达错误或者不准去的地方,欢迎指出。