说到编程,我们很容易想到两种思想:
- 面向对象编程
- 面向过程编程
这两者有什么区别呢?
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
看完上面的你相信一定没有什么感觉,的确我们如果刚刚接触编程的话,打打OJ上的水题大概率上是用不到面向对象编程思想的。那么到底什么是面向对象编程,而我们为什么要学习呢?
那么我们先来分析一下面向过程编程,C语言就是一个很好的例子。
结构化程序设计:
C语言使用结构化程序设计。
简单来说,这种结构化程序算法的组成部分就是:
程序=数据结构+算法
- 程序由全局变量以及众多相互调用的函数组成。
- 算法以函数的形式实现,用于对数据结构进行操作。
结构化程序设计的不足
-
结构化程序设计中,函数和其所操作的数据结构,没有直观的联系。
-
随着程序规模的增加,程序逐渐难以理解,很难一下子看出来:
- 某个数据结构到底有哪些函数可以对它进行操作?
- 某个函数到底是用来操作哪些数据结构的?
- 任何两个函数之间存在怎样的调用关系?
-
结构化程序设计没有“封装”和“隐藏”的概念。
要访问某个数据结构中的某个变量,就可以直接访问,那么当该变量的定义有改动的时候,就要把所有访问该变量的语句招出来修改,十分不利于程序的维护、扩充。 -
难以查错,当某个数据结构的值不正确时,难以找出到底是哪个函数导致的。
-
重用:在编写某个程序时,发现其需要的某项功能,在现有的某个程序里已经有了相同或类似的实现,那么自然希望能够将那部分代码抽取出来,在新程序中使用。
-
在结构化程序设计中,随着程序规模的增大,由于程序大量函数,变量之间的错综复杂,要抽取这部分代码,会变得十分困难。
例如:我们计算一个长方形的面积(python)
a=int(input());
b=int(input());
print(a*b);
好,如果没有任何注释,也没有我之前的“我们计算一个长方形的面积”这句话,我们看到这个代码是不是会有很多种猜测。我们可能会想到,这个程序是做两数的乘法运算,当然你也可以想到这个是长方形的面积。
但是,如果程序变得复杂呢,在未来的程序中我们可以看到上万条代码,上万个函数以及上万个变量。
综上所述,结构化程序设计的思想在程序规模扩大的时候会出现大量问题,各种变量之间的关系没有一个明面上的关系。(就像别人给你看他交的OJ题为什么错误然后一堆注释都不写,当你看着那些i,a,b,c等我们无法看出其含义的变量时,你就要花费许多时间来找出他们的关系。)那么如果是一个项目呢?当你接手别人做的项目后,看着一堆函数,一堆变量是不是很头疼?
所以我们引入了面向对象编程的思想
那么这里就要提到大多数编程语言中的类与对象
那么通过类我们可以清晰的知道变量与变量之间的关系,以及某些函数的作用等等。对于我们写代码非常有用呢!
那么面向对象的程序又如何组成呢?
面向对象的程序= 类+类+……+类
- 面向对象的程序设计方法:
- 将某类客观事物共同特点(属性)归纳出来,形成一个数据结构(可以用多个变量描述事物的属性);
- 将这类事物所能进行的行为也归纳出来,形成一个个函数,这些函数可以用来操作数据结构(这一步叫“抽象”)。
- 然后,通过某种语法形式,将数据结构和操作该数据结构的函数“捆绑”在一起,形成一个“类”,从而使得数据结构和操作该数据结构的算法呈现出显而易见的紧密关系,这就是“封装”。
- 面向对象的程序设计具有 抽象,封装,继承,多态四个基本特点。
采用面向对象的程序设计方法,我们首先考虑的不是程序该如何执行,而是应该考虑我们处理的东西是什么。
例如:我们要实现对学生成绩的处理。
对于这个问题,我们考虑的是 “东西” 就是学生,那么我们就把这个“东西”抽象一下,将其变成一个对象。
那么这个对象呢具有许多特征(这里我们叫做属性)
例如:学号,姓名,各科成绩,性别等等等。
然后,我们在生活中就需要对学生的各种特征(属性)进行各种方面的处理,这里我们叫做——对象的方法
干说无用,而且不好理解。
我们来举个比较常见的例子吧:
依然是计算长方形的面积:
"""
Calculate Rectangle Area
"""
class Rectangle:
Reccount = 0
def __init__(self, length, wide):
self.length = int(input())
self.wide = int(input())
Reccount+=1
def PrintArea(self):
print (self.length * self.wide)
a=Rectangle(1,1)
a.setvalue()
a.PrintArea()
这里我们写了一个长方形的类,其实我们就是将 长方形 抽象成一个对象,而这个对象拥有 length(长)还有wide(宽)这两个属性,然后我们对其进行计算面积就是一种操作,也就是方法
那么这个程序是不是比上面那种干巴巴的程序更加直观呢?
我们可以清晰的知道 变量 a 的数据类型就是Rectangle,然后他的函数与之联系我们也可以清楚的从中看出来。
通过一个类,我们就可以轻松解决面向过程中的难题,是不是很棒呢!
当然你会说,我也可以不用类写啊,我可以写一些函数,然后名称与之相关不就好了,然后各种属性我可以用结构体写嘛。
没错,我觉得的确是可以这样!
所以,在绝大多数面向对象的编程软件,例如C++,Java,python等当然不局限于此!
那么我们先说到这里,另外的新功能我们再慢慢讲。