面向过程和面向对象的区别

面向过程和面向对象的区别

一开始,在我们学习编程语言时,就会接触面向对象和面向过程的概念,比如:C语言是面向过程的语言,而C++是面向对象的语言,而且一般高校,都是先学习面向过程语言C,再学习面向对象C++,甚至一些非计算机类学习只学习面向过程的语言C,并且作为其必修课。但是,我们很少会统一系统的考虑两者的区别。

现在,基于我们之间的一个讨论课,总结一下两者的区别,当时也是参考了网上的很多资料,而且面向过程的资料很不好找。

两种程序设计的思想

学习一种语言,不仅仅是会使用,而且要掌握它的思想,这对于学习来说,起引导性作用。

面向过程的程序设计思想

面向过程的结构化程序设计思想:是采用面向过程的方法来设计结构化程序。结构化程序通常包含一个主过程和若干个子过程,其中每个子过程都描述了某一个小问题的解决方法,再由主过程自顶向下调用各子过程,来逐步解决整个问题。

在这里插入图片描述
如上图所示,面向过程的程序思想是主过程->子程序->……->最底层的子过程,其执行过程是从主过程的首句开始,在主过程的结束语句处结束。下面我们用C语言来类比一下。

int main(){//开始处
	//功能语句
	return 0;
}//结束处

通过观察以上C的主函数框架,我们可以,主过程对应的就是主函数,主函数开始处的“{”就是程序开始程序的地方,主函数结束处的“}”就是程序结束的地方,其中的子过程就是C语言中的子函数、功能语句。

因此我们可以知道:结构化程序设计方法本质上就是一种数学思维或计算机思维方法,它和人们认识世界时所习惯使用的方法不同。

面向对象的程序设计思想

上面介绍的面向过程的程序设计方法,它把重点放在解决问题的过程上,其存在最大的缺点是,将数据结构和操作这些数据结构的函数分开了,操作繁琐。所以,我们引入面向对象的程序设计思想。

面向对象的程序设计思想:其主要思想是将成员数据及处理这些数据的相应成员函数封装到一个类中,使用类的数据变量则称为对象。
我们在使用面向对象的程序设计方法设计软件系统时,首先要清楚软件系统中的对象,在面向对象的程序设计中,对象就是将数据和对数据进行的合法操作结合于一体的抽象实体,以这种实体所构成的程序就是面向对象的程序(对象只是某个具体类的实例化,并不等价),这种思考方法是接近于人们日常思考问题的。
在这里插入图片描述

  • 一般来说,面向对象的程序在程序结构上表现为类与类间的联系,面向对象的程序的功能是通过特定的消息传递序列来实现的。这些联系反映了程序运行时对象之间的消息(稍后介绍)传递,而程序中类之间的静态联系提供了在程序运行时对象之间的消息传递的通道。

两种程序设计的相关概念

面向过程的程序设计相关概念

面向过程:是一种以过程为中心的编程思想。首先,我们思考问题,提取去解决问题的步骤,然后通过子过程来把这些步骤分别实行,最后在主过程中按照需要重新组合调用,最终达到所需要的结果就好。

其实,面向过程的程序设计思想是最为实际的一种思考方式,也是通过代码的追溯就可以简单的达到理解程序功能。面向过程是一种基础的方法,它考虑的是实际地实现。一般的面向过程的方法是自顶向下设计,而且遵从模块化的设计,也就是说,将功能封装为一个模块,在主过程中调用。

当程序规模不是很大时,面向过程的方法还会体现出一种优势,即:程序逻辑清晰流畅(按着模块与函数的方法可以很好的组织)。

面向对象的程序设计相关概念

这部分简单来说就是:
面向对象 = 对象 + 类 + 继承 + 消息
下面,我们具体解释一下,其中涉及到的概念。

1、对象:

  • 概念:具有责任的实体。用来描述客观事物的实体,是构成系统的一个基本单位,由一组属性(静态)以及作用在这组属性的操作(动态)构成。
  • 特性:标识符(区别其他对象)、属性(状态)和操作(行为)
  • 属性(Attribute):与对象关联的数据,描述对象静态特性
  • 操作(Operation):与对象关联的程序,描述对象动态特性;

2、类:

类是定义同一类所有对象的变量和方法的蓝图或原型。例如,可以建立一个定义包含当前档位等实例变量的自行车类。这个类也定义和提供了实例方法(变档、刹车)的实现。实例变量的值由类的每个实例提供。因此,当你创建自行车类以后,必须在使用之前对它进行实例化。当创建类的实例时,就建立了这种类型的一个对象,然后系统为类定义的实例变量分配内存。然后可以调用对象的实例方法实现一些功能。相同类的实例共享相同的实例方法。

也就是说:

  • 是把属性和方法进行封装,同时对类的属性和方法进行访问控制。
  • 类是由我们根据客观事物抽象而成,形成一类事物,然后用类去定义对象,形成这类事物的具体个体。
  • 类是一个数据类型,类是抽象的,而对象是一个具体的变量,是占用内存空间的。

3、消息:

  • 概念:一个对象向其他对象发出的请求,一般包含消息接收对象,接受对象所采用的的方法、方法需要的参数、方法返回的信息等。
    4、继承:
    概念:指的是一个类(子类)继承另外的一个类(父类)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系。
    在这里插入图片描述
    下面,我们介绍一下面向对象程序设计思想的基本特征。
名称定义
封装性把过程和数据封装起来,对数据的访问只能通过已定义的方法。面向对象设计始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一系列受保护的接口访问其他对象。
继承性是一种连接类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表达共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生或子类,而原始类称为新类的基类或父类。派生类可以从父类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
抽象性抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分的注意与当前目标有关的方面。抽象并不打算了解全部问题,而是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,而是数据抽象。
多态性多态性是指允许不同类的对象对同一消息作出不同响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序同名的问题。

两种程序设计的对比

  • 面向过程/POP:是一种以事件为中心的编程思想,就是分析出解决问题,提取出解题的步骤,然后用函数把这些步骤一步一步实现,使用的时候按需调用就好。
  • 面向对象/OO:是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

下面,我们统一的对比一下。

在这里插入图片描述

两种程序设计的应用(代码)

首先,我们看一个比较实际的问题,从两种程序设计思想出发,来分别解一下这个题。
在这里插入图片描述

  • 题目1:(C语言实现)
    求组合数C(n,m)
    即:求从给定个数的n个元素中取出m个元素的方法数。
#include<stdio.h>
int factorial(int n) { //求阶乘
	int result=1;
	for(int i=1; i<=n; i++) {
		result*=i;
	}
	return result;
}
int Combination(int n,int m) { //求组合数
	int result= factorial(n)/(factorial(m)*factorial(n-m));
	return result;
}
int main() {
	int n,m,flag;
	//n为下标,m为上标,下面相同
	do{
		printf("请输入组合数的n,m:\n");
		scanf("%d%d",&n,&m);
		printf("所求组合数为:%d\n",Combination(n,m));
	printf("如果需要继续计算,请输入1:\n");
	scanf("%d",&flag); 
	}while(flag==1); 

	return 0;
}

从上面的代码我们可以看出来,我们是将问题分解为一个一个函数,然后再在主函数中按照需要调用就好。这里我们自顶向下设计,首先在主函数中我们要使用求组合数的方法,所以有了int Combination(int n,int m)函数,在组合数的函数中,我们需要求阶乘的函数,所以有了int factorial(int n) 函数,这个也是符合我们在程序设计思想部分的内容的。

题目2

从shape类中派生出来RTriangle类,并实现getArea()和getPerimeter()两个函数。

#include <iostream>
#include <cmath> 
using namespace std;

class shape {// 抽象类
public:
 virtual double getArea()=0;// 求面积
 virtual double getPerimeter()=0; // 求周长
};
class RTriangle:public shape
{
   double a,b;
   public:
	   RTriangle(double x, double y):a(x),b(y){}
   double getArea()
   {
   return a*b/2.0;
   }
   double getPerimeter()
   {
   return a+b+sqrt(a*a+b*b);
   }
};
int main()
{
  double a,b;
  cin>>a>>b;
  RTriangle t(a,b);
  cout<<t.getArea()<<endl;
  cout<<t.getPerimeter()<<endl;	
}

从上面的例子中,我们可以发现,我们将成员数据和成员方法封装到类中,当RTriangle类中存在和shape类中一样的成员方法,并且没有实现时,我们用RTriangle类继承shape类,然后得到其方法并在RTriangle类中进行实现。最后在主函数中定义对象,然后通过对象调用实例化对象的方法即可。


版权声明:本文为jianbai_原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。