举例说明面向对象和面向过程的区别


两种方法都是编程中的比较常用的方法,从理论上来说,都能达到用计算机程序来解决实际问题的目的,只不过是其中所体现出来的思想不一样而已。
面向过程:面向过程的思想是把一个项目、一件事情按照一定的顺序,从头到尾一步一步地做下去,先做什么,后做什么,一直到结束。这种思想比较好理解,其实这也是一个人做事的方法。
面向对象:面向对象的思想是把一个项目、一件事情分成更小的项目,或者说分成一个个更小的部分,每一部分负责什么方面的功能,最后再由这些部分组合而成为一个整体。这种思想比较适合多人的分工合作,就像一个大的机关,分成各个部门,每个部门分别负责某样职能,各个部门可以充分发挥自己的特色,只要符合一定前提就行了。 
举例说明1:比如刚才说的一个大的机关,要做某一个项目,从面向过程的思想来说,应该是这样分析的,先怎么样,再怎么样,最后怎么样。第一样应该如何完成,第二样应该如何完成等等。等到每一步骤都完成,项目也就完成了。而面向对象的思想则应该是这样想的,这个项目是由几个部分组成的,我们就做好分工,成立一个部门来做一个部分的功能,另一个部门来做另一个部分。各个部门可以不用理解其他部门的事,只要完成自己那一部分的事情就OK了。 
举例说明2:又比如我们有一台演出,为简单起见,假设有如下流程:主持人开场——演员一表演——演员二表演——主持人总结。用面向过程的思想来分析,就是先完成主持人开场,再完成演员一的表演,再完成演员二的表演,最后完成主持人的总结。而如果用面向对象的思想来分析,就应该是这样的。这个演出由两大部分组成:主持人、演员。与主持人相关的:开场、总结。与演员相关的:演员编号、所演的节目。然后这台演出就可以这样策划:需要一个主持人a,需


   
 


要两个演员b、c。演出的事情可以表示为:a的开场——> b、c的编号和节目——> a的总结。
        面向对象和面向过程的区别示例之 下棋
    面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。 
  例如五子棋,面向过程的设计思路就是首先分析问题的步骤: 
   1、开始游戏,    2、黑子先走,    3、绘制画面,    4、判断输赢,    5、轮到白子,    6、绘制画面,    7、判断输赢,    8、返回步骤2,    9、输出最后结果。 
  把上面每个步骤用分别的函数来实现,问题就解决了。   
  而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为: 
   1、黑白双方,这两方的行为是一模一样的,    2、棋盘系统,负责绘制画面,
   3、规则系统,负责判定诸如犯规、输赢等。 



 


  第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。 
  可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了许多步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。 
  功能上的统一保证了面向对象设计的可扩展性。比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的顺序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。 
  到这里就可以很明显的看出面向对象和面向过程的区别所在了。 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向对象与UML 第一部分 软件开发活动 7 第一章 结构化的分析与设计 8 第一节 模型图 8 业务流程图 8 数据流图 11 功能结构图 12 功能树 13 网络结构图 14 程序流程图 15 第二节 需求分析 15 需求分析的任务 15 需求分析的步骤 15 需求分析的原则 16 需求分析的方法 16 第三节 概要设计 16 概要设计任务 17 概要设计过程 17 一些概念 17 概要设计原则 17 概要设计方法 17 第四节 详细设计 18 详细设计的任务 18 详细设计的原则 18 详细设计的表示方法 18 第二章 面向对象的分析与设计 18 第一节 面向对象方法概述 18 对象与面向对象 18 面向对象技术产生的原因 19 面向对象方法的基本思想 19 概念 19 面向对象技术的特点 19 面向对象语言及系统 19 第二节 面向对象的分析 20 OOA分析的任务 20 OOA分析的原则 20 OOA分析过程 20 第三节 面向对象的设计 20 设计的模型 20 设计的三条重要原则 21 面向对象设计的概念 21 面向对象的设计方法 21 第三章 UML概述 22 UML对软件工程的重大影响 22 UML的概念模型 22 UML的建模思想 23 第四章 用UML建模 24 第一节 建模概念 24 系统、模型和视图 24 概念和现象 25 数据类型、抽象数据类型和实例 25 类、抽象类和对象 26 事件类、事件和消息 27 面向对象的建模 27 证伪和原型化 28 第二节 UML的主要图形符号 28 用例图 28 类图 35 顺序图 40 状态图 42 活动图 44 图表组织 45 图表扩展 47 第五章 需求提出 47 第一节 需求提出概述 48 第二节 需求提出的概念 50 功能性需求--系统功能 50 功能的分类 50 非功能性需求和伪需求 51 系统属性 51 描述的层次 52 用例的分类 52 用例的层次:高层用例与扩展用例 53 主要、次要和可任选的用例 53 基本用例和真实用例 53 正确性、完整性、一致性、清晰性和现实性 54 可验证性和可追溯性 55 可跟踪性 55 greenfield工程、再工程、界面工程 56 第三节 需求提出活动 56 确定执行者 56 确定场景 57 确定用例 58 改进用例 60 确定执行者和用例之间的关系 60 确定最初的分析对象 62 确定非功能性需求 63 从用户得到信息的方法 64 第六章 需求分析概述 64 需求分析的概念 65 概念模型 65 实体对象,边界对象,控制对象 67 回顾关系重数 68 受限关系 69 归纳 69 第七章 需求分析活动:从用例到对象 70 第一节 识别概念 70 识别概念的策略一 70 识别概念的策略二 71 建立概念模型的指导原则 71 几个注意点 71 自然语言分析: Abbott的试探法 72 第二节 标识实体对象 72 标识实体对象的试探法 72 例子:报告紧急情况用例 73 例子:报告紧急情况用例的实体对象 73 第三节 标识边界对象 73 标识边界对象的试探法 73 例子:报告紧急情况用例的边界对象 74 第四节 标识控制对象 74 标识控制对象的试探法 74 例子:报告紧急情况用例的控制对象 74 第五节 标识关系 75 关系的属性: 75 标识关系的试探法 75 试探关系 75 冗余关系 75 惟一标识 76 找出关联——通用关联列表 76 关联原则 76 关联的命名 77 两个类型间的多重关联 77 关联和它的实现 77 例子:销售点问题中的关联 77 第六节 标识属性 78 属性的属性 78 有效的属性类型 78 非简单属性类型 78 识别属性 79 例子:销售点系统中的属性 79 术语表 80 第八章 需求分析活动:用动态模型表示系统行为 80 系统行为 80 交互图 80 交互图:协作图与顺序图 81 交互图的依赖关系 82 顺序图--两种观点 82 系统顺序图 82 系统事件和系统操作 83 如何建立一个系统顺序图 84 系统事件和系统边界 84 系统事件和操作的命名 84 对象顺序图 85 画顺序图的试探法 86 协作图的基本表示法 87 契约 90 活动及其之间的依赖关系 90 系统行为与契约 90 契约段 91 如何建立一个契约 91 后置条件 92 后置条件应该详细到什么程度 92 描述设计细节和算法——注释 93 前置条件 93 对书写契约的一些建议 93 用例enterItem的契约 93 概念模型的修改 93 标识状态 94 事件、状态和转移 94 状态图 94 用例状态图 95 系统状态图 95 状态无关和状态相关类型 95 何处需要状态图 95 外部和内部事件 96 其他的状态图表示法 96 对单个对象的重要行为进行建模:状态图 96 第九章 GRASP: 职责分配模式 97 导言 97 职责和方法 98 UML类图表示方法 98 职责和交互图 98 模式 99 GRASP: 职责分配中通用原则的模式 99 专家 99 问题: 99 解决方案: 99 举例: 99 专家模式的优点是: 100 创建者 100 问题: 100 解决方案: 100 举例: 100 优点: 101 低耦合度 101 问题: 101 解决方案: 101 举例: 101 优点: 102 高聚合度 102 问题: 102 解决方案: 102 高聚合度例 102 具有不同功能聚合度的一些场景如: 102 优点: 103 控制者 103 问题: 103 解决方案: 103 控制者例 103 优点: 104 问题要点和讨论 104 消息处理系统和命令模式 105 相关模式 106 职责、角色扮演和CRC卡 106 GRASP: 职责分配中通用原则总结 106 多态 106 问题: 106 解决方案: 107 举例: 107 讨论 107 优点 107 纯虚构 107 问题: 107 解决方案: 107 讨论 107 优点: 108 相关模式 108 中介者 108 问题: 108 解决方案 108 举例: 108 讨论: 108 优点: 低耦合 109 相关模式 109 “不要和陌生人讲话” 109 问题: 109 解决方案: 109 举例 109 讨论 109 优点: 低耦合 110 相关模式 110 第十章 需求分析活动:精化模型 110 建立交互图的步骤 110 例:运用对象和模式设计一个解决方案 110 交互图和其他制品 110 销售点系统的协作图 111 对对象间的归纳关系建模——泛化 113 泛化 114 UML表示法: 114 定义超类型和子类型 114 何时定义一个子类型 115 销售点终端系统的类型层次 115 组织模型 116 销售点终端系统的概念模型中的包 116 检查分析模型 116 检查提问 116 分析总结 117 第十一章 系统设计 118 第一节 系统设计概况 118 分析产生的需求模型由以下结果描述: 118 系统设计得到如下结果: 118 他们特别需要解决以下问题: 119 第二节 系统设计的概念 120 子系统和类 120 服务和子系统接口 121 耦合度与相关性 121 分层和分区 124 软件体系结构 126 UML配置图 131 两个包之间的可见性 131 服务包接口——虚包模式 131 模型-视图分离模式 132 一个系统中的间接通信 132 应用协调者 133 存储和持久化 133 第三节 系统设计活动:从对象到子系统 133 起点:路线设计系统的分析模型 134 确定设计目标 135 确定子系统 137 将子系统映射到处理器和组件 138 定义连续数据的存储 140 定义访问控制 142 设计全局控制流 146 确定边界条件 147 预期变化 149 系统设计综述 150 第四节 系统设计的管理 151 记录系统设计 151 分配任务 152 与系统设计相关的交流 153 系统设计的不断反复 153 第十二章 对象设计 154 第一节 对象设计概况 155 对象设计包括4组活动 155 对象设计是非线性的。 156 第二节 对象设计概念 157 应用域对象和解决域对象回顾 157 类型、声明和可见性回顾 157 合约:不变量、前提条件和后续条件 159 UML对象约束语言(OCL) 160 第三节 对象设计活动 161 规格说明活动 161 确定遗漏的属性和操作 163 指定类型、声明和可见性 166 指定约束条件 166 指定异常情况 167 组件选择活动 168 确定并调整类库 168 确定并调整应用程序框架 169 重组活动 169 实现关系 170 提高可复用性 172 消除实现的依赖性 173 优化活动 175 回顾访问路径 175 退化对象:将对象转变成属性 176 存储高开销计算的结果 176 推迟高开销计算 176 第四节 对象设计的管理 177 用文档记录对象设计 177 分配职责 180 设计类图 180 活动及其相互之间的依赖关系 181 何时创建设计类图 181 设计类图示例 181 如何建立设计类图 181 概念模型和设计类图的对比 182 建立销售点系统的设计类图 182 识别出类并画出它们。 182 添加关联和导航 183 添加依赖关系 183 细节的表示法 184
适用于初学者 第一章: C语言概论 C语言的发展过程   C语言是在70年代初问世的。一九七八年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。同时由B.W.Kernighan和D.M.Ritchit合著了著名的“THE C PROGRAMMING LANGUAGE”一书。通常简称为《K&R》,也有人称之为《K&R》标准。但是,在《K&R》中并没有定义一个完整的标准C语言,后来由美国国家标准学会在此基础上制定了一个C 语言标准,于一九八三年发表。通常称之为ANSI C。 当代最优秀的程序设计语言   早期的C语言主要是用于UNIX系统。由于C语言的强大功能和各方面的优点逐渐为人们认识,到了八十年代,C开始进入其它操作系统,并很快在各类大、中、小和微型计算机上得到了广泛的使用。成为当代最优秀的程序设计语言之一。 C语言的特点   C语言是一种结构化语言。它层次清晰,便于按模块化方式组织程序,易于调试和维护。C语言的表现能力和处理能力极强。它不仅具有丰富的运算符和数据类型,便于实现各类复杂的数据结构。它还可以直接访问内存的物理地址,进行位(bit)一级的操作。由于C语言实现了对硬件的编程操作,因此C语言集高级语言和低级语言的功能于一体。既可用于系统软件的开发,也适合于应用软件的开发。此外,C语言还具有效率高,可移植性强等特点。因此广泛地移植到了各类各型计算机上,从而形成了多种版本的C语言。 C语言版本   目前最流行的C语言有以下几种:    ?Microsoft C 或称 MS C    ?Borland Turbo C 或称 Turbo C    ?AT&T C   这些C语言版本不仅实现了ANSI C标准,而且在此基础上各自作了一些扩充,使之更加方便、完美。 面向对象的程序设计语言   在C的基础上,一九八三年又由贝尔实验室的Bjarne Strou-strup推出了C++。 C++进一步扩充和完善了C语言,成为一种面向 对象的程序设计语言。C++目前流行的最新版本是Borland C++4.5,Symantec C++6.1,和Microsoft VisualC++ 2.0。C++提出了一些更为深入的概念,它所支持的这些面向对象的概念容易将问题空间直接地映射到程序空间,为程序员提供了一种与传统结构程序设计不同的思维方式和编程方法。因而也增加了整个语言的复杂性,掌握起来有一定难度。 C和C++   但是,C是C++的基础,C++语言和C语言在很多方面是兼容的。因此,掌握了C语言,再进一步学习C++就能以一种熟悉的语法来学习面向对象的语言,从而达到事半功倍的目的。 C源程序的结构特点   为了说明C语言源程序结构的特点,先看以下几个程序。这几个程 序由简到难,表现了C语言源程序在组成结构上的特点。虽然有关内容还未介绍,但可从这些例子中了解到组成一个C源程序的基本部分和书写格式。 main() { printf("c语言世界www.vcok.com,您好!\n"); }   main是主函数的函数名,表示这是一个主函数。每一个C源程序都必须有,且只能有一个主函数(main函数)。函数调用语句,printf函数的功能是把要输出的内容送到显示器去显示。printf函数是一个由系统定义的标准函数,可在程序中直接调用。 #include "stdio.h" #include "math.h" main() { double x,s; printf("input number:\n"); scanf("%lf",&x); s=sin(x); printf("sine of %lf is %lf\n",x,s); } 每行注释 include称为文件包含命令扩展名为.h的文件也称为头文件或首部文件 定义两个实数变量,以被后面程序使用 显示提示信息 从键盘获得一个实数x 求x的正弦,并把它赋给变量s 显示程序运算结果 main函数结束      程序的功能是从键盘输入一个数x,求x的正弦值,然后输出结果。在main()之前的两行称为预处理命令(详见后面)。预处理命令还有其它几种,这里的include 称为文件包含命令,其意义是把尖括号""或引号<>内指定的文件包含到本程序来,成为本程序的一部分。被包含的文件通常是由系统提供的,其扩展名为.h。因此也称为头文件或首部文件。C语言的头文件中包括了各个标准库函数的函数原型。因此,凡是在程序中调用一个库函数时,都必须包含该函数原型所在的头文件。在本例中,使用了三个库函数:输入函数scanf,正弦函数sin,输出函数printf。sin函数是数学函数,其头文件为math.h文件,因此在程序的主函数前用include命令包含了math.h。scanf和printf是标准输入输出函数,其头文件为stdio.h,在主函数前也用include命令包含了stdio.h文件。   需要说明的是,C语言规定对scanf和printf这两个函数可以省去对其头文件的包含命令。所以在本例中也可以删去第二行的包含命令#include。同样,在例1.1中使用了printf函数,也省略了包含命令。   在例题中的主函数体中又分为两部分,一部分为说明部分,另一部分执行部分。说明是指变量的类型说明。例题中未使用任何变量,因此无说明部分。C语言规定,源程序中所有用到的变量都必须先说明,后使用,否则将会出错。这一点是编译型高级程序设计语言的一个特点,与解释型的BASIC语言是不同的。说明部分是C源程序结构中很重要的组成部分。本例中使用了两个变量x,s,用来表示输入的自变量和sin函数值。由于sin函数要求这两个量必须是双精度浮点型,故用类型说明符double来说明这两个变量。说明部分后的四行为执行部分或称为执行语句部分,用以完成程序的功能。执行部分的第一行是输出语句,调用printf函数在显示器上输出提示字符串,请操作人员输入自变量x的值。第二行为输入语句,调用scanf函数,接受键盘上输入的数并存入变量x中。第三行是调用sin函数并把函数值送到变量s中。第四行是用printf 函数输出变量s的值,即x的正弦值。程序结束。 printf("input number:\n"); scanf("%lf",'C10F10&x); s=sin(x); printf("sine of %lf is %lf\n",'C10F10x,s);   运行本程序时,首先在显示器屏幕上给出提示串input number,这是由执行部分的第一行完成的。用户在提示下从键盘上键入某一数,如5,按下回车键,接着在屏幕上给出计算结果。 输入和输出函数   在前两个例子中用到了输入和输出函数scanf和 printf,在第三章中我们要详细介绍。这里我们先简单介绍一下它们的格式,以便下面使用。scanf和 printf这两个函数分别称为格式输入函数和格式输出函数。其意义是按指定的格式输入输出值。因此,这两个函数在括号中的参数表都由以下两部分组成: “格式控制串”,参数表  格式控制串是一个字符串,必须用双引号括起来,它表示了输入输出量的数据类型。各种类型的格式表示法可参阅第三章。在printf函数中还可以在格式控制串内出现非格式控制字符,这时在显示屏幕上将原文照印。参数表中给出了输入或输出的量。当有多个量时,用逗号间隔。例如: printf("sine of %lf is %lf\n",x,s);   其中%lf为格式字符,表示按双精度浮点数处理。它在格式串中两次现,对应了x和s两个变量。其余字符为非格式字符则照原样输出在屏幕上 int max(int a,int b); main() { int x,y,z; printf("input two numbers:\n"); scanf("%d%d",&x,&y); z=max(x,y); printf("maxmum=%d",z); } int max(int a,int b) { if(a>b)return a; else return b; } 此函数的功能是输入两个整数,输出其中的大数。 /*函数说明*/ /*主函数*/ /*变量说明*/ /*输入x,y值*/ /*调用max函数*/ /*输出*/ /*定义max函数*/ /*把结果返回主调函数*/   上面例中程序的功能是由用户输入两个整数,程序执行后输出其中较大的数。本程序由两个函数组成,主函数和max 函数。函数之间是并列关系。可从主函数中调用其它函数。max 函数的功能是比较两个数,然后把较大的数返回给主函数。max 函数是一个用户自定义函数。因此在主函数中要给出说明(程序第三行)。可见,在程序的说明部分中,不仅可以有变量说明,还可以有函数说明。关于函数的详细内容将在第五章介绍。在程序的每行后用/*和*/括起来的内容为注释部分,程序不执行注释部分。   上例中程序的执行过程是,首先在屏幕上显示提示串,请用户输入两个数,回车后由scanf函数语句接收这两个数送入变量x,y中,然后调用max函数,并把x,y 的值传送给max函数的参数a,b。在max函数中比较a,b的大小,把大者返回给主函数的变量z,最后在屏幕上输出z的值。 C源程序的结构特点 1.一个C语言源程序可以由一个或多个源文件组成。 2.每个源文件可由一个或多个函数组成。 3.一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。 4.源程序中可以有预处理命令(include 命令仅为其中的一种),预处理命令通常应放在源文件或源程序的最前面。 5.每一个说明,每一个语句都必须以分号结尾。但预处理命令,函数头和花括号“}”之后不能加分号。 6.标识符,关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,也可不再加空格来间隔。 书写程序时应遵循的规则   从书写清晰,便于阅读,理解,维护的角度出发,在书写程序时 应遵循以下规则: 1.一个说明或一个语句占一行。 2.用{} 括起来的部分,通常表示了程序的某一层次结构。{}一般与该结构语句的第一个字母对齐,并单独占一行。 3.低一层次的语句或说明可比高一层次的语句或说明缩进若干格后书写。以便看起来更加清晰,增加程序的可读性。在编程时应力求遵循这些规则,以养成良好的编程风格。 C语言的字符集   字符是组成语言的最基本的元素。C语言字符集由字母,数字,空格,标点和特殊字符组成。在字符常量,字符串常量和注释中还可以使用汉字或其它可表示的图形符号。 1.字母  小写字母a~z共26个,大写字母A~Z共26个 2.数字  0~9共10个 3.空白符 空格符、制表符、换行符等统称为空白符。空白符只在字符常量和字符串常量中起作用。在其它地方出现时,只起间隔作用, 编译程序对它们忽略。因此在程序中使用空白符与否,对程序的编译不发生影响,但在程序中适当的地方使用空白符将增加程序的清晰性和可读性。 4.标点和特殊字符 C语言词汇   在C语言中使用的词汇分为六类:标识符,关键字,运算符,分隔符,常量,注释符等。 1.标识符   在程序中使用的变量名、函数名、标号等统称为标识符。除库函数的函数名由系统定义外,其余都由用户自定义。C 规定,标识符只能是字母(A~Z,a~z)、数字(0~9)、下划线()组成的字符串,并且其第一个字符必须是字母或下划线。 以下标识符是合法的: a,x,_3x,BOOK_1,sum5 以下标识符是非法的: 3s 以数字开头 s*T 出现非法字符* -3x 以减号开头 bowy-1 出现非法字符-(减号)   在使用标识符时还必须注意以下几点: (1)标准C不限制标识符的长度,但它受各种版本的C 语言编译系统限制,同时也受到具体机器的限制。例如在某版本C 中规定标识符前八位有效,当两个标识符前八位相同时,则被认为是同一个标识符。 (2)在标识符中,大小写是有区别的。例如BOOK和book 是两个不同的标识符。 (3)标识符虽然可由程序员随意定义,但标识符是用于标识某个量的符号。因此,命名应尽量有相应的意义,以便阅读理解,作到“顾名思义”。 2.关键字   关键字是由C语言规定的具有特定意义的字符串,通常也称为保留字。用户定义的标识符不应与关键字相同。C语言的关键字分为以下几类: (1)类型说明符 用于定义、说明变量、函数或其它数据结构的类型。如前面例题中用到的int,double等 (2)语句定义符 用于表示一个语句的功能。如例1.3中用到的if else就是条件语句的语句定义符。 (3)预处理命令字 用于表示一个预处理命令。如前面各例中用到的include。 3.运算符   C语言中含有相当丰富的运算符。运算符与变量,函数一起组成表达式,表示各种运算功能。运算符由一个或多个字符组成。 4.分隔符   在C语言中采用的分隔符有逗号和空格两种。逗号主要用在类型说明和函数参数表中,分隔各个变量。空格多用于语句各单词之间,作间隔符。在关键字,标识符之间必须要有一个以上的空格符作间隔, 否则将会出现语法错误,例如把int a;写成 inta;C编译器会把inta当成一个标识符处理,其结果必然出错。 5.常量   C 语言中使用的常量可分为数字常量、字符常量、字符串常量、符号常量、转义字符等多种。在第二章中将专门给予介绍。 6.注释符   C 语言的注释符是以“/*”开头并以“*/”结尾的串。在“/*”和“*/”之间的即为注释。程序编译时,不对注释作任何处理。注释可出现在程序中的任何位置。注释用来向用户提示或解释程序的意义。在调试程序中对暂不使用的语句也可用注释符括起来,使翻译跳过不作处理,待调试结束后再去掉注释符。 资料收集:beck Copyright 2002 www.vcok.com, All Rights Reserved 初学者
什么是多态性?请举例说明。多态性有什么好处? 不同的对象收到同一消息可产生完全不同的动作,这一现象叫做多态。通俗 地说,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似 的操作,即用同样的接口访问功能不同的函数,从而实现“一个接口,多种 方法”。 多态性有以下的好处: 提高了处理问题的抽象级别; 降低了程序设计时的复杂性;(程序员只需记住一个接口,而不是好几个。) 8_2 在C++语言中实现了哪几种多态性?请说明通过什么方式实现。 在C++语言中实现了编译时多态性和运行时多态性。 编译时多态性通过函数重载,运算符重载和模板实现。模板实现的多态性又称为参数多态性。 在C++语言中运行时的多态是通过继承和虚函数实现的。 8_4 什么是静态联编?什么是动态联编? 一个源程序需要经过编译、连接,才能成为可执行代码。 上述过程中需要将一个函数调用链接上相应的函数代码,这一过程称为联编。 联编的目的是要建立函数调用与函数体之间的联系,即将一个函数调用连接到一函数的入口 地址。 静态联编:在程序被编译时进行联编;(早联编)特点是程序执行快,但灵活性较小。 动态联编:在程序运行时联编。(晚联编,滞后联编)其特点是灵活性高,程序执行慢。
前 言本书讲述了在互联网上传送数据的“盒子”的内部是如何工作的,这些“盒子”有不同的名称:网桥、路由器、交换机和集线器。本书也讲述了连接到网络上的设备。在这个领域有不少的混乱。大多数术语的定义不准确,使用时相互抵触;术语及规范的数量惊人;一些知识分布在不同的文档中,还有很多非书面的民间智慧。引起混乱的还有教条。信念被当成真理,对任何教条的置疑都会引起不满的回应。但良好的工程要求我们懂得我们在做什么,以及为什么这样做;要求我们保持开放的思想,从经验中获得知识。在本书中,我没有直接讨论某个协议的细节,而是首先集中在所要解决的问题上。我考查了每个问题的多种解决方法,讨论其中涉及的工程折衷。然后我检查已经应用的方案,对这些方案进行比较。对任何观点,我都给出了技术上的理由,如果你认为我遗落了某些论据,欢迎通过电子邮件与我进行讨论。我的电子邮件地址附在书后,希望你从头到尾读过本书后才能找到它。在本书第1版中,我的意图是帮助人们理解问题和通常的解决方案,而假定他们会去阅读规范以得到特定协议的细节。但人们不仅利用本书来理解问题,还把它当作参考书。因此在本版中,我收录了更多的协议细节。我认为,要深入了解某件东西必须把它与其它东西作比较。第1版是“最小化”的,因为我常只举两个例子:两种网桥,网桥与路由器,面向连接的与无连接的网络层协议,两个无连接的协议(CLNP和IP)。在本版中我增加了更多的例子,包括ATM、IPv6、IPX、AppleTalk和DECnet。这样做,部分是因为这些协议存在着,并且较难找到相关的信息。但更主要的,是因为这些协议体现了不该错过的有趣的想法。当我们设计新协议时,应该学习以前的想法,无论是好的还是坏的。另外,在对问题作了一般描述之后,就很容易讨论一些例子。本书导读前四章与第1版中的相应部分没有明显的不同,但其余部分已大量重写。第1章至第4章包括了一般网络概念、数据链路问题(如编址和复用)、透明桥和生成树算法及源路由网桥。第5章是全新的,解释了交换的概念如何演变到重新发现网桥。它也包括了VLAN和快速以太网。余下部分集中在第三层(网络层)。第6章是网络层概览,第7章涉及面向连接的网络,包括ATM和X.25。第8章讨论无连接网络层的一般问题,第9章包括了第三层中的一般编址技术,详尽比较了IP、IPv6、CLNP、DECnet、AppleTalk和IPX。第10章谈到在网络层报头中应出现的信息及几种协议报头的对比。第11章涉及自动配置和近邻发现,包括ARP和DHCP协议。第12章是一般的路由选择算法。第13章讨论最长前缀匹配问题,这在快速转发IP包时需要。第14章讨论各种路由选择协议的特点,包括RIP、IS-IS、OSPF、PNNI、NLSP和BGP。第15章是网络层组播。第16章说明如何设计免受破坏的网络,这在将来会有用。最后两章总结了本书,我希望它们是轻松有趣的。第17章探究了将网桥和路由器区别开来的秘密,第18章试图收集人们有关如何设计协议的经验知识。最后有一张术语表。我在第一次使用某个术语时会给出定义,但如果我没有给出定义,你也可以从术语表中找到。 本书被认为是讲述网络理论和实践的主要书籍之一。除介绍了一般的网络概念外,对路由算法和协议、编址、网桥、路由器、交换机和集线器的功能结构等都提供了权威和全面的信息。包括网络领域的最新发展,如交换和桥接技术、VLAN、快速以太网、DHCP、ATM以及IPv6等。作者以专家的洞察力分析了网络的运作过程和工作机理,并深入到技术背后的概念和原理,帮助读者获得对可用的解决方案的更深理解。本书适用于作为大专院校计算机专业本科生网络课程的教材,也适用于从事网络研究的技术人员和其他对网络技术有兴趣的人员。 译者序 前言 第1章 网络基本概念 1 1.1 网络分层模型 1 1.2 服务模型 5 1.3 网络的重要特性 7 1.4 可靠的数据传输协议 9 第2章 数据链路层 14 2.1 一般的LAN 14 2.1.1 什么是局域网 14 2.1.2 轮转 15 2.2 IEEE 802 LAN 16 2.3 名字、地址与路由 17 2.4 局域网地址 18 2.5 组播地址与单播地址 19 2.6 广播地址 20 2.7 复用字段 20 2.8 位序 23 2.9 逻辑链路控制 24 2.10 802.3中的问题 25 2.11 802.5中的问题 27 2.12 包的突发性 28 2.13 需要网桥的理由 28 2.14 点对点链路 29 第3章 透明网桥 32 3.1 纯网桥 32 3.2 学习式网桥 33 3.3 生成树算法 41 3.3.1 配置消息 42 3.3.2 计算根ID以及到根网桥的费用 44 3.3.3 选择生成树的端口 44 3.3.4 一个例子 45 3.4 生成树算法的改进 45 3.4.1 故障 46 3.4.2 避免临时循环 47 3.4.3 站点缓冲区超时值 49 3.4.4 网络范围的参数 50 3.4.5 端口ID 51 3.4.6 分配端口号 52 3.4.7 性能问题 53 3.4.8 单向连通 53 3.4.9 可设参数 54 3.5 网桥报文格式 55 3.5.1 配置信息格式 55 3.5.2 拓扑变化通告信息的格式 56 3.6 其他的网桥问题 57 3.6.1 多连接的站点 57 3.6.2 配置过滤器 58 3.6.3 网桥的不完全透明 60 3.7 远程网桥 62 第4章 源路由网桥 68 4.1 纯源路由 68 4.1.1 路由信息报头 68 4.1.2 网桥编号 69 4.1.3 网桥算法 72 4.2 SR-TB网桥 74 4.2.1 从TB端口发出的包 74 4.2.2 从SR端口发出的包 75 4.2.3 环 76 4.3 SRT网桥 77 4.4 端系统算法 78 4.4.1 什么时候寻找路由 78 4.4.2 怎样发现一个路由 79 4.4.3 通过目的端发现路由 83 4.4.4 路由选择 83 4.5 源路由与透明网桥 83 4.5.1 带宽费用 83 4.5.2 配置难易度 84 4.5.3 普遍性 84 4.5.4 网桥的费用和性能 85 4.6 改善源路由网桥的方法 85 4.6.1 源路由网桥的自动配置 85 4.6.2 使指数级的开销固定 86 第5章 集线器、交换机、虚拟局域网与 快速以太网 90 5.1 集线器 90 5.1.1 学习式HUB和安全性 91 5.1.2 存储-转发和生成树 91 5.1.3 混合L1和L2的交换机 92 5.1.4 产品与标准,L1与L2 93 5.2 快速LAN 93 5.3 虚拟局域网 95 5.3.1 为什么需要虚拟局域网 96 5.3.2 映射端口到虚拟局域网 97 5.3.3 举例:虚拟局域网使用独立路由器 转发 97 5.3.4 举例:虚拟局域网使用交换机作为 路由器转发 98 5.3.5 动态绑定链路到虚拟局域网 99 5.3.6 动态虚拟局域网绑定,交换机- 交换机 101 第6章 网络接口:服务模型 104 6.1 什么是网络层 104 6.2 网络服务类型 104 6.2.1 性能保证 105 6.2.2 服务模型选择举例 105 6.2.3 混合策略 106 6.2.4 无连接与面向连接 107 第7章 面向连接的网络:X.25和ATM 110 7.1 一般的面向连接的网络 110 7.2 X.25:可靠的面向连接服务 111 7.2.1 基本思想 112 7.2.2 虚电路号 113 7.2.3 呼叫建立 113 7.2.4 数据转发 114 7.2.5 流控制 117 7.2.6 功能 119 7.2.7 呼叫释放 119 7.2.8 中断 120 7.3 在网络内部实现X.25 120 7.3.1 电路方法 120 7.3.2 基于数据报的可靠连接方法 121 7.3.3 比较 121 7.4 异步传输模式 121 7.4.1 信元大小 122 7.4.2 虚电路和虚路径 122 7.4.3 ATM服务种类 124 7.4.4 ATM信元头部格式 124 7.4.5 连接的建立与释放 125 7.4.6 ATM适应层 126 第8章 一般的无连接的服务 129 8.1 数据传输 129 8.2 地址 129 8.3 跳计数 129 8.4 服务类型信息 130 8.4.1 优先级 130 8.4.2 带宽预留和服务保证 131 8.4.3 特别的路由计算 131 8.5 网络反馈 132 8.6 分段和重组 132 8.7 最大包的发现 133 第9章 网络层地址 135 9.1 有固定边界的分层地址 135 9.2 有活动边界的分层地址 136 9.3 自有地址和租用地址 137 9.4 地址类型 138 9.5 IP 138 9.5.1 IP地址规定 140 9.5.2 IP地址文字表示 141 9.6 IPX 141 9.6.1 采用唯一ID的保密性问题 142 9.6.2 对IPX恶意的中伤 142 9.6.3 IPX地址管理 142 9.6.4 内部IPX网络号 143 9.7 IPX+ 144 9.8 IPv6 145 9.8.1 IPv6版本编号由来 146 9.8.2 IPv6地址的书写表示 146 9.8.3 IPv6前缀的书写表示 146 9.8.4 EUI-64 147 9.8.5 IPv6中用的EUI-64类型 148 9.8.6 IPv6地址约定 148 9.8.7 从IPv4到IPv6的转换 149 9.9 CLNP网络层地址 149 9.9.1 自动配置 151 9.9.2 内嵌的DTE地址 151 9.10 AppleTalk网络层地址 152 9.11 DECnet Phase 3和Phase 4 153 9.11.1 位的来由 153 9.11.2 DECnet Phase 4地址 153 9.11.3 从DECnet 地址到以太网地址的 映射 153 9.12 NAT/NAPT 154 第10章 无连接数据包格式 156 10.1 无连接网络层的几个部分 156 10.2 数据包 156 10.3 包格式汇总以便参阅 157 10.3.1 IP 157 10.3.2 IPX 157 10.3.3 IPX+ 158 10.3.4 AppleTalk 159 10.3.5 IPv6 160 10.3.6 DECnet 160 10.3.7 CLNP 161 10.4 数据包格式的技术特征与比较 162 10.4.1 目的地址 162 10.4.2 源地址 163 10.4.3 目标与源套接字 163 10.4.4 报头长度 163 10.4.5 包长度 163 10.4.6 报头校验和 164 10.4.7 允许分段 164 10.4.8 包标识 165 10.4.9 分段偏移 165 10.4.10 预分段长度 166 10.4.11 多分段 166 10.4.12 寿命 166 10.4.13 版本号 168 10.4.14 填充 168 10.4.15 协议 168 10.4.16 类型 169 10.4.17 错误报告要求 169 10.4.18 拥塞反馈:源抑制与DEC位 170 10.4.19 服务类型 171 10.4.20 选项 173 10.5 源路由 176 10.5.1 松源路由和紧源路由 177 10.5.2 用一个外出的链路地址重写源 路由 178 10.5.3 用外出的链路地址重写一个目的 地址 178 10.5.4 有源路由选项的安全漏洞 178 10.6 IPX帧格式的大秘诀 179 10.6.1 IPX的四种帧格式 179 10.6.2 多重IPX帧格式的处理 180 10.7 给端节点的出错报告和其他网络 反馈 181 10.7.1 CLNP错误报文 181 10.7.2 ICMP:IP错误报文 182 10.7.3 IPv6错误报文 185 第11章 邻机问候和自动配置 188 11.1 经由点到点链路相连的端节点 188 11.2 经由LAN相连的端节点 189 11.2.1 ES-IS:CLNP的解决方案 190 11.2.2 IP的解决方案 192 11.2.3 IPX的解决方案 197 11.2.4 DECnet的解决方案 198 11.2.5 AppleTalk的解决方案 198 11.2.6 IPv6的解决方案 200 11.2.7 回顾和比较 200 11.2.8 比较 201 11.3 通过非广播的多路访问媒体相连的 端节点 202 11.3.1 不同的解决方案 202 11.3.2 在协议Y的网络中提供组播 203 11.3.3 LAN仿真 205 11.3.4 传统的IP及ARP over ATM 206 11.3.5 去除额外的跳 207 11.4 查找 208 11.4.1 一般性的查找服务 208 11.4.2 AppleTalk的方案 209 11.4.3 NetWare的服务通告协议 210 第12章 路由选择算法概念 212 12.1 距离向量路由 212 12.2 链路状态路由 217 12.2.1 与邻机会话 218 12.2.2 构建一个LSP 218 12.2.3 给所有路由器散播LSP 218 12.2.4 计算路由 224 12.3 链路状态和距离向量路由的比较 225 12.3.1 内存 225 12.3.2 带宽耗费 227 12.3.3 计算量 227 12.3.4 对计算成本的说明 228 12.3.5 健壮性 228 12.3.6 功能性 229 12.3.7 收敛速度 229 12.4 负载分割 230 12.5 链路代价 231 12.6 迁移路由算法 233 12.6.1 运行两个算法 233 12.6.2 人工逐个节点切换 233 12.6.3 转换 234 12.7 LAN 234 12.7.1 把LAN当成一个节点 234 12.7.2 散布路由信息 236 12.8 服务类型 237 12.8.1 处理指令 237 12.8.2 多种度量 237 12.8.3 基于策略的路由和约束 239 12.8.4 静态路由 240 12.8.5 过滤器 240 12.8.6 源路由 240 12.8.7 路由域特有的策略 240 12.8.8 服务类别特有的策略 241 12.9 划分修复:第1层子网划分 242 第13章 快速包转发 245 13.1 使用附加报头 245 13.2 地址前缀匹配 246 13.3 使用Trie算法的最长前缀匹配 247 13.3.1 倒塌一个无分支的长路径 248 13.3.2 以存储空间换取查找时间 248 13.3.3 前缀长度的二分查找 251 13.3.4 利用特殊硬件实现并行性 252 13.4 二分查找 255 13.4.1 前缀排序 255 13.4.2 给用1填充的前缀增加前缀长度 255 13.4.3 排除重复的填充前缀 256 13.4.4 k-ary查找 257 13.4.5 做一次查询 257 第14章 特定的路由协议 259 14.1 域内路由协议简史 259 14.2 RIP 260 14.3 RTMP、IPX-RIP和DECnet 262 14.4 IS-IS、OSPF、NLSP和PNNI 263 14.4.1 层次结构 263 14.4.2 区域地址 268 14.4.3 LAN与指定路由器 269 14.4.4 LAN上LSP的可靠传播 270 14.4.5 参数同步 272 14.4.6 每个包的目的地数目 273 14.4.7 LSP数据库过载 273 14.4.8 认证 274 14.4.9 IS-IS细节 275 14.4.10 OSPF 288 14.4.11 PNNI细节 300 14.5 域间路由协议 301 14.5.1 静态路由 301 14.5.2 EGP 302 14.5.3 BGP 307 第15章 广域网组播 317 15.1 简介 317 15.1.1 第2层组播 317 15.1.2 第3层组播的原因 317 15.1.3 需要考虑的方面 318 15.1.4 (非IP中的)多跳组播 319 15.2 IP中的组播 319 15.2.1 集中式的组播与分散式的组播 320 15.2.2 可以不用第3层组播吗 321 15.2.3 映射NL组播到DL组播 321 15.2.4 IGMP协议 322 15.2.5 IGMP探听 323 15.2.6 反向路径转发 323 15.2.7 距离向量组播路由协议 324 15.2.8 组播OSPF 325 15.2.9 基于核心的树 327 15.2.10 PIM-DM 328 15.2.11 PIM-SM 328 15.2.12 BGMP/MASC 329 15.2.13 组播源分布协议 330 15.2.14 简化组播 330 第16章 防破坏的路由 337 16.1 问题 337 16.2 需要了解的密码系统知识 337 16.3 方法概述 339 16.3.1 强健扩散 339 16.3.2 强健路由 340 16.4 方法的详细描述 340 16.4.1 再谈强健扩散 340 16.4.2 强健的包路由器 343 16.4.3 其他的动态数据库 343 16.5 小结 345 16.6 其他参考资料 345 第17章 路由、桥接,还是交换: 是问题吗 347 17.1 交换机 347 17.2 网桥与路由器 347 17.3 网桥的扩展 349 17.3.1 不只是使用生成树 349 17.3.2 分段网桥 349 17.3.3 IGMP探听 349 17.4 路由器的扩展 350 17.4.1 更快的路由器 350 17.4.2 多协议路由器 350 17.4.3 单协议主干 351 17.4.4 Brouter 352 第18章 协议设计中的诀窍 353 18.1 简单性、灵活性与最优性 353 18.2 了解需要解决的问题 354 18.3 开销与升级 354 18.4 超出能力时的操作 355 18.5 紧凑ID与对象标识符 355 18.6 最普遍或最重要情况的最优化 356 18.7 向前兼容 357 18.7.1 足够大的字段 357 18.7.2 层的独立性 357 18.7.3 保留字段 358 18.7.4 单个版本号字段 358 18.7.5 分割版本号字段 358 18.7.6 选项 359 18.8 迁移:路由算法与编址 359 18.9 参数 360 18.9.1 避免参数 361 18.9.2 合法的参数设置 361 18.10 使多协议操作成为可能 362 18.11 在第3层与第2层上运行 363 18.12 健壮性 364 18.13 决定性与稳定性 365 18.14 实现正确性的性能要求 365 18.15 结束语 366 术语 367
当涉及到大型软件项目时,面向对象编程(OOP)比面向过程编程(POP)更具优势。以下是一些OOP相对于POP的优势: 1. 封装:OOP允许将数据和函数捆绑在一起以创建类。封装使得代码更加安全,同时也提供了更好的抽象和代码重用。这个特性可以帮助我们控制数据的访问和修改。 以下是一个使用类和封装的示例代码: ```python class BankAccount: def __init__(self, balance=0): self.balance = balance def deposit(self, amount): self.balance += amount def withdraw(self, amount): if self.balance >= amount: self.balance -= amount else: print("Insufficient balance") account = BankAccount(1000) account.deposit(500) account.withdraw(200) print(account.balance) ``` 上述代码中,我们创建了一个名为BankAccount的类,并定义了三个方法:__init__、deposit和withdraw。这个类允许我们使用封装来隐藏余额和其他数据。我们可以通过调用deposit和withdraw方法来修改余额,但无法直接访问余额。 2. 继承:OOP中的继承允许我们创建一个新的类,它从现有的类派生而来。这使得我们可以重用现有的代码并创建更具抽象性的类。 以下是一个使用继承的示例代码: ```python class Animal: def __init__(self, name): self.name = name def speak(self): pass class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" animals = [Dog("Rufus"), Cat("Whiskers"), Dog("Buddy")] for animal in animals: print(animal.name + ": " + animal.speak()) ``` 上述代码中,我们创建了一个名为Animal的基类,并定义了一个方法speak。然后,我们创建了两个继承Animal的子类Dog和Cat,并重写了speak方法。最后,我们创建了一个包含不同类型动物的列表,并使用循环打印每个动物的名称和它们的声音。 3. 多态:OOP允许多态,即对同一方法的调用可以根据对象类型的不同而产生不同的行为。这使得代码更加灵活和可扩展。 以下是一个使用多态的示例代码: ```python class Shape: def area(self): pass class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius * self.radius shapes = [Rectangle(5, 10), Circle(7), Rectangle(3, 6)] for shape in shapes: print("Area:", shape.area()) ``` 上述代码中,我们定义了一个名为Shape的基类,并定义了一个方法area。然后,我们创建了两个子类Rectangle和Circle,并重写了area方法。最后,我们创建了一个包含不同形状的列表,并使用循环打印每个形状的面积。 这些是OOP相对于POP的一些优势。虽然具体情况可能会有所不同,但在大型软件项目和复杂问题解决方案中,OOP通常是更好的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值