面向对象语言发展史

3.1面向对象语言发展史

    讲解面向对象的编程之前,我们先介绍面向对象语言的发展史,和计算机的历程一样,面向对象语言是逐渐发展出来的,真实的历史有些古板枯燥,网络上有篇编程语言的戏谑版的介绍(真实的历史,加戏谑史),

如表3-1,我们引用其中和面向对象与ABAP相关的部分,结合实际的历史为计算机的重要发展历程和面向对象语言的发展历程做一个简介。

原帖见以下链接: <http://james-iry.blogspot.co.at/2009/05/brief-incomplete-and-mostly-wrong.html>[原帖引用] ,图像与历史数据来自于维基百科 [引用 2]

1

戏谑版历史

真实历史

 

1801年 – 法国人雅卡尔(Joseph Marie Jacquard)用打孔卡为一台织布机编写指令,在挂毯上织出了"hello, world"字样。

当时的网友对这项工作的反响并不热烈,因为它既缺少尾递归调用,又不支持并发,而且甚至都没有注意在拼写时恰当地区分大小写。[原帖引用]

雅卡尔织布机是第一台通过打孔卡片进行程序化控制提花的织布机。虽然是织布机,但它被认为是计算硬件历史上的重要先驱,早期的计算机,例如1944年IBM自动序列控制计算器(Harvard Mark I)是从类似于提花卡的带有孔的纸带中接收到程序指令,然后执行计算。

直到20世纪80年代的中期,打孔卡仍然被用于计算机设备中。[引用 2]

 

2

戏谑版历史

真实历史

 

1842年 - Ada Lovelace写了世界上第一个程序。

她的努力只遇到了一点点小小的麻烦,那就是:实际上并没有任何计算机能够用来运行她的程序。[原帖引用]

埃达·洛夫莱斯(1815年 - 1852年)是英国数学家与作家,她为查尔斯·巴贝奇的分析机(一种机械式的通用计算机,但并没有被完整地制造出来)的设计编写注记。在她的注记中,包含了一段公认为史上第一个程序算法,可以运用在分析机上。因此,埃达被公认为史上第一位程序员。

 

1980年12月,美国国防部发布了一种计算机编程语言,命名为Ada,用于纪念埃达。

 

洛夫莱斯是埃达的夫姓,埃达的娘家姓是Byron,她的父亲是英国著名诗人拜伦(Byron)。[引用 2]

 

 

 

 

 

 

 

3

戏谑版历史

真实历史

 

1936年 - Alan Turing发明了世间一切程序语言的最终形态。

但很快他就被英国军情六处"请"去当007了,以至于他根本来不及为这些语言申请专利。[原帖引用]

阿兰·图灵(1912年 - 1954年)英国计算机科学家、数学家、逻辑学家、密码分析学家和理论生物学家,他被视为计算机科学与人工智能之父。

 

图灵提出的著名的图灵机模型为现代计算机的逻辑工作方式奠定了基础。其中的图灵完备概念(Turing completeness),定义了计算机程序语言的标准。

 

1939年图灵被招入英国军方,并在英国军情六处监督下从事对德国军事密码的破译工作。两年后他的小组成功破译了德国的密码系统Enigma,从而使得英军对德国的军事指挥和计划了如指掌。

 

计算机协会(ACM)于1966年设立的图灵奖,是计算机界最负盛名的奖项,有"计算机界诺贝尔奖"之称。

 

图灵还是一位世界级的马拉松运动员,马拉松最好成绩是2小时46分3秒。[引用 2]

 

 

图灵所破解的恩尼格玛密码机(德语:Enigma,又译哑谜机)是一种用于加密与解密文件的密码机,此破译被认为使得盟军在西欧的胜利提前了两年。[引用 2]

4

戏谑版历史

真实历史

 

1946年 – 第一台电子计算机出现了,采用布线和开关来进行程序控制。

工程师们当时这么做,据说是为了避开"用空格还是用制表符缩进"这样的争论。[原帖引用]

电子数值积分计算机ENIAC(Electronic Numerical Integrator And Computer)是世界上第一台通用计算机。它是图灵完备的电子计算机,于1946年2月由美国宾夕法尼亚大学研制完成,能够重新编程,解决多种计算问题。

ENIAC包含了2万个真空管,重量达27吨,采用IBM的卡片阅读器用于输入,打卡器用于输出。[引用 2]

 

 

两位ENIAC程序员在运用敏捷开发方法进行愉快的结对编程。[原帖引用](实际上敏捷开发概念在1990年代才发布)。(图片来自于http://www.columbia.edu

ENIAC计算机是由美国军方投资立项,用于解决核武器研制中大量的数据计算问题,其中一位用户是正在参与核武器研制的匈牙利裔美国数学家冯·诺依曼(John von Neumann,1903 -1957),诺依曼的父亲是匈牙利的银行业大亨,身为一个富二代,诺依曼却始终热衷于科研工作。

早期的ENIAC没有存储器,程序由布线板控制(如图3-5),处理的数据则由卡片阅读器输入,每次进行新的计算要用几天时间搭接布线,效率低下。1945年,身为甲方用户(Key User)的冯·诺依曼给项目组提出了解决方案:把程序本身也作为数据来对待,程序和需要被计算的数据用同样的方式存储,他也确定了计算机的各大组成部分和基本工作方法,这也就是后来的"冯·诺依曼体系结构",深刻影响了计算机的设计和发展。(这就是"别人家的甲方",虽然冯·诺依曼本人被称为"计算机之父",实际上诺依曼是二十世纪最重要的数学家之一,他在多个领域(量子力学,经济学,数学等)都有重大贡献,"提出现代计算机体系结构"是他众多成就中最被世人熟知的,却只是他的业余之作而已。)

5

戏谑版历史

真实历史

 

1959年 - Grace Hopper和她的团队发明了"面向模板的全大写化语言(Capitalization Of Boilerplate Oriented Language,COBOL)"。[原帖引用]

COBOL,普通商用电脑语言(Common Business Oriented Language),是最早的高阶编程语言,以及是世界上最早实施标准化的计算机语言之一。

1959年5月,美国国防部委托葛丽丝·霍普博士领导一个委员会,制定了COBOL语言的标准。

COBOL是一种面向数据处理的,面向文件的,面向过程的高级编程语言,是一种功能很强而又冗长的语言,习惯上全部用大写字母编程。

COBOL语言直接影响了ABAP语言的设计。[引用 2]

 

 

 

 

 

霍普的"First actual case of bug being found"的工作日记,现存于华盛顿美国国家历史博物馆(大家发现没有,那时候的程序员竟然可以早八晚五的工作)。

 

葛丽丝·穆雷·霍普 (Grace Murray Hopper,1906年-1992年),美国海军准将(Rear admiral)及计算机科学家,世界最早的程序员之一。她是Harvard Mark I上第一个专职程序员,以及第一个高级商用计算机程序语言"COBOL"的发明者,被誉为"COBOL 之母"。

计算机术语"Debug"(调试排错)就源于她的工作日记,她也被称为"Debug 之母"。

 

1947年9月9日,葛丽丝·霍普发现了第一个电脑上的bug,当在Harvard Mark II计算机上工作时,工作团队发现电脑不能正常运作了。经过排查,发现原来是一只飞蛾飞入了一台电脑电路开关而引起的故障。霍普在日记本中记录下了这一事件,称之为"Bug"。并将那只飞蛾贴在日记本中。因此,人们逐渐用"Bug"来称呼计算机中的隐藏的错误。

6

戏谑版历史

真实历史

 

1970年 – Niklaus Wirth创造了Pascal,一个过程式的语言。

很快就有人开始声讨Pascal,因为它使用了类似"x := x + y"这样的语法,而不是更为人熟知的类C语法"x = x + y"。

尽管存在着这样的批评,而事实上当时C还没有被发明出来。[原帖引用]

Pascal是一个有影响的面向对象和面向过程编程语言,由尼克劳斯·维尔特在1968年9月设计,在1970年发行,作为一个小型的和高效的语言,意图鼓励使用结构化编程和数据结构进行良好的编程实践。[引用 2]

Object Pascal是Pascal的面向对象编程设计的派生语言,其集成开发环境就是著名的Delphi。

Pascal语言影响了Ada, Object Pascal, Java等语言的设计。

Delphi的设计者丹麦人安德斯·海尔斯伯格(Anders Hejlsberg,1960年-),从Borland公司被挖到微软公司后,主持设计了.NET。[引用 2]

 

 

 

 

使用Delphi编写的著名软件有Skype,WPS(早期),KMplayer,GoldWave等,国内还有一个网络病毒"熊猫烧香"(2006年)也是用Delphi写成的。

 

Delphi/Object Pascal语言曾经风靡一时, 至今也被广泛应用,2017年5月TIOBE排名为第18位。

 

尼克劳斯·埃米尔·维尔特(德语:Niklaus Emil Wirth,1934年-),瑞士计算机科学家。

他写的一本书的书名Algorithms + Data Structures = Programs(算法+数据结构=程序)是计算机科学的名句。[引用 2]

尼克劳斯·维尔特的姓名曾按错误的英文读法,被错译为"尼古拉斯·沃斯"。欧洲人通常都将他的名字读得正确,读作"Nih-klaus Virt";但美国人通常读成"Nickel's Worth"近似的发音("Nickel's Worth"中文意为"值五分钱" [引用 2])。

有人开玩笑说,欧洲人传址调用他,美国人传值调用他 ("nickel's worth", he is called by name in Europe and called by value in America.)[引用 2]

1984年"值五分钱"的维尔特教授因发展Pascal,Modular等语言而获图灵奖,奖金为二十五万美元。(2014年后,Google赞助ACM将图灵奖奖金提高到一百万美元,和诺贝尔奖奖金相近)。[引用 2]

7

戏谑版历史

真实历史

 

1972年 – Dennis Ritchie发明了一把能同时向前和向后两个方向发射的武器。

但他对此发明造成的误伤数量感到还不够满意,所以他又发明了C语言和Unix。[原帖引用]

C是一种通用的编程语言,广泛用于系统软件与应用软件的开发。

于1969年至1973年间,为了移植与开发UNIX操作系统,由丹尼斯·里奇与肯·汤普逊,以B语言为基础,在贝尔实验室设计开发出来。[引用 2]

C语言具有高效、灵活、功能丰富、表达力强和较高的可移植性等特点,在程序员中备受青睐,成为最近25年使用最为广泛的编程语言之一。

目前,C语言编译器普遍存在于各种不同的操作系统中,例如Microsoft Windows, Mac OS X, Linux, Unix等。

C语言的设计影响了众多后来的编程语言,例如C++,Objective-C,Java,C#等。[引用 2]

操作系统Linux, 版本工具git的后台核心系统都是使用纯C语言创建的。

大多数程序员并不严格区分C与C++,工程项目中用C++和C配合使用的情况也很普遍。

 

 

 

丹尼斯·里奇和布莱恩·柯林汉合作出版的《C程序设计语言》(中文翻译版),言辞简洁明了,是程序员写给程序员的书。

 

丹尼斯·麦卡利斯泰尔·里奇(Dennis MacAlistair Ritchie,1941年-2011年)是美国著名的计算机科学家。他是C语言的创造者,Unix操作系统的关键开发者,对计算机领域产生了深远影响,1983年里奇与肯·汤普逊共同获得图灵奖。[引用 2]

今天C语言广泛用于各种应用程序,操作系统与嵌入式系统的开发之中,并影响了大多数现代编程语言。[引用 2]

不夸张的说,目前人们应用的各种软件与网络应用,都带有C和Unix的DNA。

8

戏谑版历史

真实历史

 

1972年 - Alain Colmerauer设计了逻辑编程语言Prolog。

他的目标是创造一个具有两岁小孩智商的程序语言。

为了证明他成功达到了这个目标,他展示了一个Prolog程序,它对于每条查询都会机智地给出相同的回答:"No"。[原帖引用]

Prolog(Programming in Logic)是一种逻辑编程语言。

它创建在逻辑学的理论基础之上, 最初被运用于自然语言等研究领域。现在它已广泛的应用在人工智能的研究中,它可以用来建造专家系统、自然语言理解、智能知识库等。

Prolog的子集Datalog用于专门与大型关系数据库交互,最终影响了SQL的设计与出现。

SQL(结构化查询语言(Structured Query Language),是用于数据库中的标准数据查询语言,1987年由国际标准组织设立为国际标准。

SQL语言也直接影响了ABAP语言的设计。[引用 2]

Prolog目前依然是广泛应用的人工智能语言,2017年5月的TIOBE排名为第35位。

 

 

 

 

图3-9是国内某特大型钢铁集团的科研项目的前端界面(论文已公开发表),展示了生产计划的甘特图排产结果,系统的后端核心的排产模型即是采用Prolog语言开发的专家系统,能够智能编排最优的生产计划,基于Prolog语言的专家系统是由我当年的同事,东北大学俞胜平博士设计开发的。

上图的可编辑计划的智能调度平台是由作者在2004年使用C++开发的(职务发明),其国家专利号为:CN103646098A。

9

戏谑版历史

真实历史

 

1980年 – Alan Kay创造了Smalltalk并发明了"面向对象"这个词。

当被问到它的含义时,他回答道:"Smalltalk程序本身就是对象。"

当被问到对象是由什么组成时,他回答到:"对象。"

当再一次被问到这个问题时,他说"看,它从里到外都是对象。直到你抽出一只乌龟。" [原帖引用]

Smalltalk面向对象语言由艾伦·凯于70年代初开始在施乐公司帕罗奥图研究中心(Xerox PARC)开发。

Smalltalk的设计从很大程度上受到了Logo语言,也就是著名的小海龟教学语言的影响。

90年代的许多软件开发思想得利于Smalltalk,例如设计模式,敏捷编程和代码重构等。Smalltalk也直接影响了C++,Java等语言的设计。

艾伦·科提斯·凯(Alan Curtis Kay,1940年-),美国计算机科学家,在面向对象编程和窗口式图形用户界面方面作出了先驱性贡献,他是Smalltalk的最初设计者。2003年的图灵奖被颁予了艾伦·凯,表彰他在面向对象编程领域的贡献。

 

艾伦·凯也是一位专业的爵士吉他手,年轻时曾以教授吉他演奏为业。[引用 2]

 

 

 

 

《史蒂夫·乔布斯传》 [引用 4]中,对Smalltalk语言有所描写:1979年12月,作为可购入苹果公司原始股票的回报,施乐公司邀请苹果公司乔布斯一行在帕罗奥图中心参观。在苹果方面的反复要求下,施乐公司终于展示了核心的技术秘密,Smalltalk语言展示了三项惊人的成果,包括计算机联网,面向对象程序设计和图形界面。[引用 4]

乔布斯被其中的图形界面所震惊,"我看到了计算机产业的未来" [4]。这直接导致了苹果Lisa电脑和麦金塔电脑(Macintosh,如图3-10)的诞生,个人电脑开启了图形界面GUI的时代。

乔布斯偶尔也会骄傲地承认对施乐PARC的技术盗窃,说"好的艺术家只是照抄,而伟大的艺术家窃取灵感。" [引用 4]

10

戏谑版历史

真实历史

 

1983年 – Bjarne Stroustrup把他所听说过的一切都试图嫁接到C上,创造出了C++。

最后得到的语言是如此地复杂,以至于程序必须被送到未来去让"天网"人工智能进行编译。

编译时间难以容忍。天网开展这项服务的动机仍然不为人知,但来自未来的发言人说道:"没什么好担心的,宝贝。"带着一口奥地利腔的机械口音。有一些来自坊间的推测,所谓的天网只不过是个自命不凡的缓冲区溢出而已。[原帖引用]

比雅尼·斯特劳斯特鲁普博士在20世纪80年代,在贝尔实验室工作期间发明并实现了C++。

C++是一种广泛使用的计算机程序设计语言(大多使用在大型系统和应用软件中)。支持过程化程序设计,数据抽象化,面向对象程序设计,泛型程序设,基于原则设计等。

C++是一门复杂的语言、这门语言拥有过多的特性从而难以彻底掌握。[引用 2]

 

 

 

 

2002年10月,Bjarne Stroustrup博士访问清华大学,据当时负责接待的老师回忆,博士为人随和,毫无架子,还有点站没站相,坐没坐相。

 

与 C++ 相比,C 具备相对容易学习,编译速度快,显式描述细节,标准变动小等优点。

而C++ 在语言层面上提供了面向对象的语法,更严格的类型检查,异常控制,并提供更丰富的标准库。

 

掌握全部C++的语法和功能实现的复杂度已经超出包括发明者本人在内的,世界上所有人的个人能力 (Stroustrup曾说他自己最多掌握C++ 14的70%的功能)。

但在优秀的开发者团队和良好的项目管理下,采用C++有很多成功的开发案例,如:

大多数的操作系统:如Windows系列,Apple Mac OS,Google Chrome OS等。(例外是Linux是基于纯粹的C语言的,Linux的发明者Linus本人推崇C而非C++)。

浏览器:IE,Chrome是C++编写的。

办公软件: 微软Office系列和Outlook是C++编写的,新版的WPS是基于C++ Qt框架开发的。

媒体和图像软件:Apple iPod software还有Adobe Photoshop 等。

几乎所有主流的数据库:Oracle database,MySQL,IBM DB2,Microsoft SQL Server,SAP DB/MaxDB, SAP HANA 都是C++编写的。

几乎所有的网络游戏或游戏引擎如: 星际争霸StarCraft,魔兽世界Warcraft,等都是C++编写的。[2]

大型应用软件:SAP ECC(ABAP的内核由C++编写,然后再用ABAP开发ECC系统本身。)

程序语言编译器内核:Java,ABAP等。[引用 2]

11

ABAP语言的发展

 

ABAP是80年代由SAP公司研发的,为其物料管理和财务会计管理系统SAP R/2设计的开发语言,传统的ABAP受到了COBOL 语言和SQL语言的影响。[引用2]

 

1999年,SAP发布了SAP R/3 Release 4.6,同时也发布了面向对象的ABAP 语言(Object Oriented ABAP)。从向对象的设计上看,面向对象的ABAP参考了C++和Java的设计。 [引用2]

 

SAP ABAP的版本从 ABAP for ERP (ABAP Version 7.01, 7.02,7.31),目前已经升级到了ABAP for HANA(ABAP 7.40,7.50,7.51).

SAP的PaaS(Platform as a Service)云平台SAP Cloud Platform也支持ABAP语言开发。

3.2 面向对象的理论基础

面向对象的理论基础是基于心理学的认知发展论(Cognitive-developmental theory),该理论是瑞士心理学家让·皮亚杰(Jean Piaget,1896年-1980年)所提出,核心思想是人类发展的本质是对环境的适应,它是一个主动的学习过程,在与环境的相互作用过程中,认知逐渐成熟起来。

 

1967年,麻省理工学院的西摩尔·派普特(Seymour Aubrey Papert,1928年-2016年)根据皮亚杰的认知发展理论,以LISP语言为基础,开发了为儿童启蒙电脑的Logo编程语言,Logo也就是我们小时候很多人学习过的"小海龟"语言。

1968年,Alan Kay向派普特学习了Logo语言,同时也学习了皮亚杰,杰罗姆·布鲁纳,维果斯基等心理学理论,这都影响了他的眼界和观点。[引用 2]

在加入施乐Palo Alto研究中心后,Alan Kay提出了Dynabook电脑的概念,并为之开发出Smalltalk语言。面向对象语言的概念继Simula 67语言后,有了更为完善的理论和完善的集成开发环境。

 

"理论是灰色的,而生命之树常青"(《浮士德》靡菲斯特语)。如果仅有理论,没有实践,则是无法验证实际效果的。自80年代中期到90年代,经过先驱们不断地探索和实践,面向对象语言走向繁荣,世界上涌现了大批具有工程实际意义的面向对象的程序语言,如C++, Objective-C, Object Pascal, Java等,这些语言一般都具有语言类库,框架和可视化编程环境,在工程实践中应用十分广泛,用实际的应用验证了面向对象理论的有效性。

 

面向对象的理论基础是源于人类对对象的理解和认知,是自然的,符合人性的一种描述事物的方式。

 

曾经有批评说,面向对象理论不具有严格的数学理论基础,比如关系型数据库理论是有严格的集合代数理论做理论基础的,是可以证明哪些设计是最优的(比如用范式衡量)。而面向对象的设计好坏就很难用数学方法衡量。

这也说的没错,因为面向对象所依赖的是人类的认知理论,属于心理学范畴。心理学当然是一种科学,但衡量起来就更加复杂。我们至今也不是很清楚如何用数学来表达心理学中人类的认知过程,比如人类知识体系的建立过程,人类的情感,人类的好奇心,想象力等。

在目前热门的人工智能领域,理解和实现人类的认知是人工智能的发展核心方向之一。就像斯坦福大学的图像识别人工智能专家李飞飞的观点"要深究我们视觉世界的意义,那么认知是最核心的任务"。

你看,目前风口浪尖上的人工智能的前沿研究和面向对象设计竟然指向了相同的理论基础,大家学习面向对象理论时是不是开始心里有点小激动了呢?

 

 

3.3 面向对象的概念 - 对象(Object)

识别物体对象是人类与生俱来的能力,在皮亚杰的心理学研究中,初生婴儿只能通过"这里"与"现在"(也就是此地此时)来理解这个世界,只有那些能感觉到和接触到的东西才是真实的。

对初生婴儿来说,一个递给他的玩具小球能够吸引他的注意,他也能识别这个小球,但当小球滚下床,不再被婴儿看见,摸到,咀嚼到,对于婴儿来说,小球就已经不存在了,婴儿也不会试图去寻找被藏起来的小球。

通过不断的主动的认知和学习,到了婴儿两岁以后,婴儿才会逐渐认知到滚到床下的小球仍然存在,只是在床上看不见而已。这表示2岁的人类婴儿已经理解了对象永存(object permanence)这一概念。

 

Grady Booch的《面向对象分析与设计(第3版)》[引用3]中,定义了什么是对象,从人类认知的角度出发,对象是下列事物之一:

  • 一个可以被触摸或可以看见的东西。
  • 在人类的智力上可以理解的东西。
  • 可以指导思考或行动的东西。

按作者的理解,对象就是这样的东西:

  • 一个可以被触摸或可以看见的东西,如一台笔记本电脑,一辆汽车,一位学生,(我们说的"一切皆对象"大概是这个角度上的意义)。
  • 不是可见可触摸的,但在人类的智力上可以理解的东西。如银行系统的一个账户,信用卡消费的积分,网络中传输的一个数据包。
  • 不是可见可触摸的,甚至是我们不能理解的东西,但依然可以用于指导我们思考或行动。比如工程领域利用"重力"来计算结构受力(重力/引力的原理远比中学物理中阐述的复杂,用广义相对论才能精确解释原理,但我们依然可以当常数引用它来来指导工程计算)。比如C++的STL类库中复杂的算法的实现,或者如SAS软件或者R语言中封装的统计学方法,或者自己封装的方法类库,即便程序员不理解类库中方法的原理和意义,也能调用函数和方法计算出想要的结果。

 

我们所特定的对象(Object)是指"一种具有状态,行为和属性的实体。"对象可以是真实的,也可以是抽象的,可以在程序解决的现实世界的业务的领域中承担定义良好的角色[引用3]

我们在下一节讨论对象与类的关系中再深入说明对象。

3.4 面向对象的概念 - 类(Class)

类(Class)这个单词,在牛津词典中的定义是:一组有着共同特性的事物,和其他的事物在类别,类型,质量上有所区别。(A set or category of things having some property or attribute in common and differentiated from others by kind, type, or quality. )

类是一组事物,拥有共同的结构和共同的行为。类(Class)是基于对象(Object)进行的进一步的抽象。比如"人类",代表了所有人的共同的特征的抽象。我们具体的每一个人,就是"人类"的一个具体的"对象"。

在面向对象程序中,我们可以描述说"对象是类的一个实例",对象是一个具体的存在,而类是一种抽象的概念。

在面向对象程序中,如果说类是对象的一个定义模板,那么对象就是类的一个运行实例(instance)。我们可以创建多个基于同一个类的对象,每一个实例化的对象都有一个特定的身份来标识,并可以被赋予不同的属性值。

在面向对象程序中,可以认为,软件在编写时,是以"类"的形式来定义事物的,而软件运行状态下,类被实例化成为对象,对象自身承载了具体业务的操作数据和方法,执行预定的业务功能。

在面向对象程序中,类是指一段包含了数据属性(Attributes),并能定义了服务方法(Methods)的声明。

类的属性(Attributes),定义了类所能承载的数据,表明了类的属性,用于描述类实例化为对象后的状态。

类的方法(Methods),指明类具有的功能。数据和服务包成了一个整体,能够有一系列的行为和动作。

类的概念可以帮助程序设计者将现实问题和软件代码对应起来。

 

程序中对类的定义的一个原则是以业务需求来进行的,从业务需求的角度进行观察,按业务需要将具有相似属性的事物定义成为类,具体的规则可以参考第9.1节。

3.5 类之间的关系

为了用类来表述业务,除了用类封装属性和方法,还需要用类之间的关系来表述业务的业务逻辑和关系。

引用 《设计模式的艺术》[引用 5]一书的说明,我们用UML语言和图表来表示这些常见的类的关系。

UML (Unified Modeling Language),也就是统一建模语言是非专利的第三代建模和规约语言,用于描述面向对象程序的分析和设计过程。

 

我们使用了UML中的类图用于表达类,接口和子系统间的关系,类图中包括了类名,类的属性,类的方法,并表示了类之间的关系。

本书并不会详细讲解UML图,所以我们在以后的图示中,会加入文字注释来帮助说明类之间的关系。

 

第一种,关联关系(Association),是类之间比较常见的关系,表示的是两个类之间"有关联"的关系。一般来说,就是一个类的对象是另一个类的变量。

 

1.1双向关联关系

如图3-12所示,双向关联用无箭头的实线表示,表示两个类互相关联,比如乘客和机票的关系是:乘客可以购买多张机票,而每一张售出的机票都会指向固定的乘客。

双向关联关系就是两个类互为对方的类属性。

 

1.2 单向关联关系

如图3-13所示,单向关联用带单向箭头的实线表示,两个一个类拥有另一个类,比如乘客和联系地址的关系是:乘客Passenger 拥有联系地址,而联系地址并不拥有乘客。

单向的关联除了一对一,也可以有一对多等,如一个乘客拥有多个电话联系方式等。

单向关联关系就是类B是类A的属性(A指向B)。

 

2.聚合关系

如图3-14所示,聚合(Aggregation),表示整体和部分的关系,是has-a的关系,表示一个类是另一个类的组成部分(属性),但他们之间是可以独立存在的。UML中用带空心的菱形表示整体对象,用箭头表示被拥有方,比如,一台电脑拥有一块CPU,电脑和CPU都可以独立地存在。

聚合关系与关联关系的区别是,聚合关系一般用属性做构造方法CONSTRUCTOR的参数,从而在构造类时初始化属性(对象构造注入);或者用属性做方法的参数,在调用方方法时初始化属性(对象设值注入)。

聚合关系就是类B是类A的属性,并且在这个类A的方法中还要使用这个类B做参数,A,B两个类之间是可以独立存在的。

 

 

 

3.组合关系

如图3-15所示,组合(Composition),也是一种表示整体和部分的关系,是contains-a的关系,表示一个类是另一个类的组成部分(属性),但他们之间是不可以独立存在的。UML中用带实心的菱形表示整体对象,用箭头表示被拥有方,比如,一个公司有一个部门,但公司如果不存在了,也就不会单独的存在一个部门。

组合关系一般也用属性做构造方法CONSTRUCTOR的参数,从而在构造类时初始化属性(对象构造注入);或者用属性做方法的参数,在调用方方法时初始化属性(对象设值注入)。

组合关系就是类B是类A的属性,并且在这个类A的方法中还要使用这个类B做参数,类B是不可以独立于类A存在的。

 

 

 

4.依赖关系

如图3-16所示,依赖(Dependency),表示一种类之间的调用关系,是关联性较弱的关系,一般来说都是一个类中的方法,使用另一个类的对象作为参数。UML中用带箭头的虚线来表明使用关系。线头指向被调用方,比如,一个客户类有一个方法"传真文档",使用了传真机类的对象作为参数,并在方法内部调用传真机类的"开始传真"方法。

依赖关系就是类B是类A的方法中的参数(A指向B)。

 

5.泛化关系

如图3-17所示,泛化(Generalization),也就是我们常说的继承关系,是父类和子类之间的层次关系。UML中用带空心三角形箭头的实心线表示,箭头指向父类。

如物料类可以分为原料类,半成品类,成品类。泛化关系就是类B是类A的子类(B指向A)。

 

6.实现关系

如图3-18所示,实现(Realization),就是实现类对接口的实现关系,接口是一类约定和声明,表明了一种功能,实现类对接口进行代码实现,有类似功能的一组实现类可以对同一个接口进行实现。 UML中用带空心三角形箭头的虚线表示,箭头指向接口。

如接口交通工具中具有一个可载货方法,卡车类,客车类都可以实现这一个载货的方法。

实现关系就是类B实现了接口A。(B指向A)。

如图3-19所示,我们用一个图例来表示这些类之间的关系,后续章节的类图中会出现这些类关系。

 

 

 

 

 

posted @ 2018-10-12 22:01  techtalk  阅读(1876)  评论(1)    收藏  举报