1.简单对比
1.面向过程编程:
过程:是具体完成某个具体任务的代码,基本可以理解为函数
面向过程编程的核心,就是把要实现的某件事情,拆分成一个个步骤依次完成。
比如: 我们要去ATM机存钱,依次存入50,取出100块钱,那我们就依次写步骤并定义出存钱和取钱的函数。
存钱(50)
取钱(100)
function 存钱(面值){
}
function 取钱(面值){
}
如果我们还需要记录存钱和取钱的详细信息,例如:在哪个ATM机器上操作的,在哪个银行操作的,纸币的编号,那就需要补充参数
存钱(50,"001","招商银行","111111")
取钱(100,"004","中国银行","121212")
function 存钱(面值,ATM编号,银行,纸币编号){
}
function 取钱(面值,ATM编号,银行,纸币编号){
}
虽然这种写法没啥毛病,但是如果我们要记录更多的性质,比如:ATM所属支行,纸币发行年份等等,这些散落的数据一方面会增加函数参数的数量,另一方面:ATM有编号,纸币也有编号,这些数据在传参过程中混在一起并不利于我们理解具体的含义。
随着程序长度和逻辑复杂度的增加,代码的清晰度可能会降低。
2.面向对象:(OOP:Object、Oriented、Programming)
相比过程来说,他以对象为核心,他对于同样的问题并不是考虑先去存钱还是取钱,他会模拟真实的世界,先考虑各个对象有什么性质、能做什么事情
比如:
那我们就可以提取出来这些性质,定义ATM类,然后用类创建对象。
类和对象之间的关系就是:类是创建对象的模版,对象是类的实例
class ATM(){
constructor(编号,银行,支行){
this.编号 = 编号;
this.银行 = 银行;
this.支行 = 支行;
}
}
//创建ATM对象
atm1 = new ATM("001","招商银行","普陀支行");
atm2 = new ATM("004","中国银行","静安支行");
同理我们就也可以创建纸币类
class money(){
constructor(编号,面值,发行年份){
this.编号 = 编号;
this.面值 = 面值;
this.发行年份 = 发行年份;
}
}
//创建纸币对象
纸币1= new money1("111111","50","2000");
纸币2= new money2("121212","100","2023");
面向对象除了能让参数更少之外,用对象把相关属性绑定在一起,还能让程序更加清晰。
比如说虽然ATM和纸币都有编号,但我们能通过atm1.编号可以获取属于atm1的编号
能通过纸币1.编号可以获取属于纸币1的编号
就能让人更加清楚性质所属于的对象是什么
- 假如我们去取钱的时候还要打印记录,如果不用对象的话,就需要把一大堆的参数都给传递过去
function 存钱 (ATM编号, 银行, 纸币编号, 支行, 发行年份)
function 打印记录 ("存钱" ,面值, ATM编号, 银行, 纸币编号, 支行 , 发行年份)
- 但是有了对象之后,就可以直接通过对象来获取与他绑定的属性,这会让逻辑和数据后续的流动更加清晰
function 存钱 (ATM对象,纸币对象)
function 打印记录 ("存钱" ,ATM对象,纸币对象)
- 除了属性之外,另一个能和对象绑定的是方法,正如真实世界里对象拥有不同的属性,并且能做不同的事情
function 放(被放的物品,放入的物品)
function 开机(机器)
function 清洗(需要清洗的物品)
function 烘干(需要烘干的物品)
放("衣物","洗衣机")
放("洗衣粉","洗衣机")
开机("洗衣机")
清洗("衣服")
烘干("衣服")
- 面向过程他就像说明书一样,一步步指导执行各个步骤
- 面向对象在这里面,人、洗衣机都是执行事务的对象,人能放东西和开机,洗衣机能够清洗和烘干衣服。
class 人(){
放(被放的物品,放入的物品){}
开机(机器){}
}
class 洗衣机(){
清洗(需要清洗的物品){}
烘干(需要烘干的物品){}
}
换个角度来看所谓的方法也就是放在类里面的函数,所谓属性也就是放在类里面的变量
定义好类之后就可以通过类来创建对象,然后让各个对象去执行这些方法,相比面向过程编程直接聚焦于按照步骤执行,面向对象编程:把事务先分解到对象身上,描述各个对象的作用,然后才是他们之间的交互
我 = 人()
我的洗衣机 = 洗衣机()
我.放("衣服",我的洗衣机)
我.开机(我的洗衣机)
我的洗衣机.清洗("衣服")
我的洗衣机.烘干("衣服")
2.面向对象的特性
- 封装
表示写类的人将内部实现细节隐藏起来,使用类的人只通过外部接口访问和使用,接口可以大致被理解为提供使用的方法。
比如说已经有人写好了洗衣机这个类,其实我们只需要知道他有什么方法,方法有啥作用,具体怎么用就足够了,不需要知道里面是怎么写的
好处:封装能减少我们对不必要细节的精力投入
- 继承
面向对象编程允许创建有层次的类,类有子类和父类来表示从属关系
比如:小学生、大学生都是学生,都应该有学号、年级的属性,都要去学校,这两个类的共同之处导致会有很多重复代码产生,那我们就可以创建出一个学生的父类,然后让小学生和大学生去继承这个类。
好处:是父类的属性方法都可以被继承,不需要反复的定义,减少代码的冗余
- 多态
指的是:因为对象具体类的不同而有不同的表现
比如:虽然小学生和大学生都要写作业,但是难度肯定是不一样的,所以这个写作业的方法就不能直接定义在父类里面,而是要分别定义在子类里面,否则大小学生用的就是同一个方法
作为家长就不需要管做什么作业,他们会因为所属类的不同调用不同的做作业方法,这就是多态
class 小学生(){
写作业(){
//写简单作业
}
}
class 大学生(){
写作业(){
//写困难作业
}
}
如果不使用类的话,我们就需要用if判断崽子的类型,手动调用不同的写作业函数
好处:让你可以无需判断,统一调用统一名称的方法
3.结束
但这也不是说面向对象一定优于面向过程,只能说选择哪个还是得根据具体的场景需求。