《UML面向对象设计基础》—第1章1.6节类

1.6 类
UML面向对象设计基础
回想一下在机器人软件中,通过执行Hominoid.New创建了一个对象(表示一个机器人)。Hominoid(类的一个例子)作为创建机器人对象(如句柄为602237 的对象)的模型。每当执行语句Hominoid.New时,示例一个与用Hominoid.New创建的每一个对象结构相同的对象。“结构相同”,指每个机器人对象与其他对象有相同的操作和变量,特别是当程序员编码写Hominoid类时的操作和变量。参见图1.13

类(class)是创建(示例)对象的模板。从类示例出的每个对象具有相同结构和行为。
如果对象obj属于类C,则称“obj为C的一个实例”。

同一个类的对象之间有两点不同:一是每个对象具有不同的句柄;二是在任何特定时刻,每个对象可能有不同的状态(指存储在变量中的不同“值”)。

开始你可能对一个类和一个对象之间的区别比较模糊。下面提供了区别两者的简单方法:

类是用于设计和编程的。
对象是运行时(由类)创建的。
流行软件包对于类和对象提供了非常好的类比。比如你从Wallisoft Corp购买了电子表格软件包Visigoth 5.0。软件包本身好比类。由此创建的电子表格好比对象。每个电子表格具有作为类Visigoth 的一个实例应有的“电子表格结构”。

在运行时,一个类如Hominoid可以产生3个、300个或3000个对象(即Hominoid的实例)。因此一个类类似于一个模板:一旦模板的形状被剪裁,就可以仿制上千次。所有的仿制品都是相同的,当然与原来的模板形状也是相同的。

为清楚地说明这个问题,让我们更进一步地看一下从一个类产生的对象。正如我们所知,一个类的所有对象都具有相同的结构:相同的一组操作和属性(注:方法是操作的实现。用编程术语讲,可以将方法看作是过程或函数体的程序。类似地,变量是属性的实现,句柄是对象标识符的实现)。因此类的每个对象(事例)都具有自身实现操作的一组方法和实现属性的一组变量的拷贝。在给定的时间内,原则上讲有多少对象被示例,就有多少方法和变量被拷贝。如图1.14所示。

如果读者不介意,我将深入到计算机内部实现,进一步解释相同类(如类C)的一组对象的真实结构。假设实现图1.14中的操作的每个方法占100个字节,每个变量占2个字节,每个句柄占6个字节。因此,object1将占416个字节的内存(4100+52+6)。因此三个对象一共占用1248个字节(3416)。十五个这样的对象将占用6240个字节(15416)。
但用这种方法给对象分配内存是非常浪费的,因为15个对象的15组方法是相同的。由于每组方法只包含过程代码,一个代码集可以被所有的对象共享。因此,尽管原则上讲每个对象具有自己的操作方法,但实际上(为节省空间)它们都共享同一个物理拷贝。

另一方面,尽管每个对象的句柄和变量在结构上是相同的,但他们不能被对象共享。因为它们在运行时必须含有不同的值。

因此,由于C的所有对象都共享同一组操作,C的15个对象实际占用内存空间只有640个字节(一组方法占用400字节,15组变量占用150字节,15个句柄占用90个字节)。640字节比6240字节要节省得多,这也是面向对象环境中给对象分配内存的通常方式。参见图1.15。

在本章提到的几乎所有操作和属性都属于每个对象。它们被称为对象实例操作和对象实例属性或简称为实例操作和实例属性。然而,还有类操作和类属性。对于给定类总是存在一组类操作和类属性,不管该类产生了多少对象。
类操作和类属性需要应付不能被任何对象表示的状态。类操作最著名的例子就是New,它示例一个给定类的新对象。

消息New 不能发送给某个对象。例如,我们有类BankCustomer的三个对象,表示银行的实际客户(假设这三个对象分别为bob,carol和ted),我们想示例一个新BankCustomer对象(如alice)。给哪个对象发送消息New呢?没有什么理由发送给bob,发送给carol或ted 也没道理。更糟糕的是,永远不能示例第一个银行客户,因为开始时没有任何BankCustomer 类的对象可以向其发送New消息。

因此,New是一个必须发送给类而不是发送给对象的消息。机器人游戏中的Hominoid.New就是一个例子。这是一个发送给类Honinoid的类消息,执行类操作New建立一个新对象,即类Hominoid的新实例。

类属性的一个例子是noOfHominoidsCreated:Integer。New每执行一次,该值增加一次。然而尽管有许多机器人对象,但只有该类属性的一个拷贝。可以设计一个类操作供给外界访问该类属性。

图1.16示意了具有两个类操作(每个方法占100字节)和三个类属性(每个变量占2字节)的类C的内存结构。“类结构”的字节数(本例为206)仍然不变,无论C示例了多少对象。随着类实例的增加,C及其15个对象一共占用846个字节(即206+640)内存空间。

注意原则上和实际中每个类都只有一组类方法。这点与实例方法不同,因为其原则上每个对象有一组方法(只是为了节省内存使对象的操作共享相同的方法)。类变量和实例变量的区别十分明显:每个类只有一组类变量,而类的每个对象无论在原则上还是在实际上都只有一组实例变量。
如果你学习过抽象数据类型(ADTs),可能想知道类和ADT 之间的区别。则答案是:ADT描述的是接口。它只描述向ADT用户提供的功能,但并不说明ADT如何实现这些功能。而类是实现ADT的具体内容(或至少具有内部设计和代码)。实际上,对于给定的ADT,可以设计和建立几个不同的类。例如,一些类可以产生运行效率非常高的对象,而对于同一个ADT的另一些类可以产生占用内存少的对象。

本书的第三部分更详细地介绍有关抽象数据类型、类及它们之间的区别。 在此之前,可以将“类”和“ADT”看作是同义词。请把这一点记在脑子里,现在让我们转到讨论继承的重要概念。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-09-28 23:22:24

《UML面向对象设计基础》—第1章1.6节类的相关文章

《UML面向对象设计基础》—第1章1.10节本章小结

1.10 本章小结 UML面向对象设计基础 因为"面向对象"在英语中就没有绝对优势的定义,因此,针对面向对象定义的特性从来就没有一致的意见.我本人认为以下特性对面向对象是至关重要的:封装.信息/实现隐藏.状态保持.对象标识.消息.类.继承.多态性及一般性. 面向对象的封装产生一个由表示对象状态的属性及其操作组成的软件结构("对象"),用实现的术语讲,就是操作的方法处理保持对象状态的变量.封装确保对对象内部信息的任何修改(或访问)都必须通过对象的操作. 信息/实现隐藏

《UML面向对象设计基础》—第1章1.9节一般性

1.9 一般性 UML面向对象设计基础 一般性(genericity)指一个或多个类内部使用的类C的结构,仅在运行时(即示例类C的对象时)才提供. 说明一般概念的最好方式是讲述一个不堪回首的故事.当时我还是一名大学生,学习一门数据结构(Data Structures)的课程101.有一个学期,Rossini 教授给我们留了一项作业,设计和编程整数有序平衡二叉树(见图1.22).平衡二叉树的主要特点是所有的叶子在同层上拉平. 在往树中插入另一个整数(如5 ,见图1.23)之前,一切顺利.插入整数5

《UML面向对象设计基础》—第2章2.4节面向对象的益处

2.4 面向对象的益处 UML面向对象设计基础 本节的题目既迎合愤世嫉俗者又符合盲从者. 一些反对者可能会说面向对象没有什么优点:它仅是一种流派或是一场从西方一些地区引发起的全球性阴谋.而一些激进派则宣称面向对象是一流的并且是所有软件成功的唯一途径.面向对象不仅适用于Windows系统,而且还适用于无所不能的分布式Web体系结构. 这两种说法都太极端.作者认为面向对象是有用的,但不能神化,它还不够完美,其特定实用程序依赖于在软件开发过程中的使用方法. 没有一种有价值的软件工程方法可以成为"当年时

《UML面向对象设计基础》—第2章2.1节面向对象的起源

第2章 面向对象简史 UML面向对象设计基础 前面讨论了面向对象的固有特性,现在来看一下面向对象是如何适用于软件开发的广阔领域. 当听说Wolfgang Pauli教授提出一种新的基本粒子(μ介子,μ- meson或muon)时,Isidor I .Rabi教授曾经立即予以反驳:"谁承认这种说法?"鉴于此事例,我在本章开头部分列出一些对面向对象有贡献的人士.下面将面向对象置于社会环境中,讨论对这种软件方法的看法.然后,将面向对象置于工程环境中,将面向对象与电子学做一个类比.最后,阐述面

《UML面向对象设计基础》—第2章2.2节面向对象的成熟期

2.2 面向对象的成熟期 UML面向对象设计基础 本节介绍软件工业如何促进面向对象时代的真正到来. 老生物学家们常爱发表这样的言论:个体生物重演了生物发展史.其含义是个体生物胚胎的发展通常演绎着生物整体发展的进化过程(如人类胚胎的发育过程).当然在时间上存在很大的差异.个体生物的发展可能只有几个月,而整体生物却世代繁衍. 尽管老生物学家的说法无庸置疑,但在软件工程中却出现了一种新观点:面向对象软件工程的历史重演了传统软件工程的历史.当然在时间跨度上也存在很大的差异.形成成熟的过程和数据库结构花费

《UML面向对象设计基础》—第2章2.5节本章小结

2.5 本章小结 UML面向对象设计基础 在面向对象中有一种说法,即面向对象构件与电子集成电路有些类似.至少在软件中有机会象现代电子工程师那样构造系统:可以通过预制构件的连接实现有效的抽象.但为了实现这一点,首先必须标识正确的软件抽象,然后以构造的方式进行联接. 要想掌握"软件集成电路"的技术,就必须广泛而深入地研究面向对象."面向对象"是一个术语,融合了从20世纪60年代到现在许多软件研究者的思想.但并非所有人都赞成这个观点.一些激进派认为面向对象是对过去的一个完

《UML面向对象设计基础》—第1章1.5节消息

1.5 消息 UML面向对象设计基础 对象通过消息请求另一个对象执行活动.许多消息还具有将信息从一个对象传送给另一个对象的作用.大多数老前辈都将消息列为重要的面向对象特性. 消息(message)是发送对象obj1向目标对象obj2发送请求的载体,申请对象obj2的一个方法. 本节对消息特性进行了剖析,描述了消息参数的特点,发送消息对象的角色,接收消息对象的角色及消息的三种类型. 1.5.1 消息结构 消息由几个含义组成,每个含义在面向对象设计中都十分重要.实际上,本书从头到尾会多次用到消息的特

《UML面向对象设计基础》—第1章1.3节状态保持

1.3 状态保持UML面向对象设计基础面向对象的第三个抽象概念是对象具有保持状态的能力.当传统的过程模块(函数.子程序.过程等)返回到调用者时,不会带来任何负作用,模块运行结束,只是将其结果返回.当同一模块再次被调用时就象是第一次诞生一样.模块对以前的存在没有任何记忆,就像人类一样对以前的存在一无所知. 但对于对象而言,如机器人对象就知道它的过去.对象在其自身内部将信息保留一段时间.例如,一个对象的"调用者"可能给该对象一个信息,后来该调用者或其他调用者又要求该对象再次提供这一信息.也

《UML面向对象设计基础》—第2章2.3节类似工程学的面向对象

2.3 类似工程学的面向对象UML面向对象设计基础20世纪80年代,Brad Cox用某种类似现代生活中用到的硬件集成电路(IC)的方式看待软件对象(参见[Cox,1986]).当华盛顿大学的考古学家们在我办公室的一堆论文中寻找时,我想起了这个类比.他们发现一本Merrill Skolnik著的<雷达系统导论>(Introduction to Radar System),在书中Skolnik先生提出下面的观点: 电子工程可以根据以下分类: 组件:技术:系统.组件是可以组合的基本构造单元,通过使

《UML面向对象设计基础》—第2章2.6节习题

2.6 习题UML面向对象设计基础① 本书引用了大量比喻.随着对本书内容的体会,分析软件对象类与电子集成电路之间类比的缺陷. ② 根据你对面向对象的了解,你属于反对派.进化派.激进派中的哪一种?通过面向对象的开发与传统主流软件开发的对比,调整你的位置. ③ 你认为企业有必要选择一种语言(开发环境)具有第一章描述的面向对象的所有特性吗?换言之,你赞同一些面向对象的激进派对一些企业选择部分面向对象特性而不是全部面向对象特性持讥讽态度吗? ④ 回顾一下2.1节提到的面向对象功名录.是否有遗漏?如果是这