《数据结构与抽象:Java语言描述(原书第4版)》一1.2 说明一个包

可以使用UML将方法表示为:

且将这行添加到类图中。
可以使用一个布尔值方法来测试包是否为空,同样该方法没有参数。用伪代码及UML描述这个方法的规格说明


将这行添加到类图中。

注:因为通过查看getCurrentSize是否返回0就能检测包何时为空,所以并不真的需要操作isEmpty。但是它是所谓的便利方法(convenience method),所以很多集合都提供这样一个操作。
现在想向包中添加给定的对象。可以将这个方法命名为add,并有一个表示新项的参数。可以写出下列伪代码:

我们可能试图让add作为void方法,但是会有一些情况,比如如果包满则不能将新项添加到包中。这些情况下,我们该如何办呢?

设计决策:当不能添加新项时,方法add将如何处理?

当add不能完成任务时,我们可采取下面两种选择:
什么也不做。不能添加其他的项,所以忽略这个项并且不改变包。
不改变包,但告诉客户添加是不可能的。
第一个选择简单,但会让客户疑惑到底发生了什么。当然,我们可以规定add的前置条件,即包必须不满。这样客户要负责避免将新项添加到满包中。
第二个选择更好一些,且它也不难说明或实现。我们如何告诉客户添加是否成功?标准Java接口Collection规定,如果添加没有成功则发生异常。稍后我们再完成这个方法,并且使用另一种方式。显示一条错误信息并不是好的选择,因为你应该让客户决定所有的书面输出。因为添加操作或者成功或者不成功,所以我们可以让方法add返回一个布尔值。

因此,可以用UML规范add方法:

其中T表
示newEntry的数据类型。

自测题1 假定aBag表示一个有有限容量的空包。写伪代码,将用户提供的字符串添加到包中,直到操作失败。

有3个动作涉及从包中删除项:删除所有的项;删除任意一项;删除某个项。假定我们用伪代码为这些方法命名并说明其参数,如下所示:

这些方法的返回类型是什么?
方法clear可以是一个void方法:我们只想要一个空包,不获取它的任何内容。所以,在UML中方法写为:

如果第一个remove方法从包中删除一项,则该方法可以简单地返回被删除的对象。它的返回类型为T,这是包中项的数据类型。在UML中,我们有

现在,我们可以处理从返回null的空包中删除对象了。
如果包中不含有某项,则第二个remove方法不能从包中删除该项。可以让方法返回一个布尔值,类似于add那样,用它来表示成功与否。或者,方法可以返回被删对象,或者,如果不能删除这个对象则返回null。下面是用UML表示的规格说明的两种可能版本——我们必须二选一:

或者

如果anEntry等于包中的某项,则这个方法的第一个版本将删除该项并返回真(true)。即使方法没有返回被删除的项,客户也能有方法的参数anEntry,它等于被删除的项。故我们选择这个版本,它与接口Collection是一致的。

自测题2 在一个类内同时具有上面描述的remove(anEntry)的两个版本合法吗?

解释。
自测题3 在一个类内同时具有remove的两个版本,一个不带参数而另一个带一个参数,这样合法吗?解释。
自测题4 给出自测题1中创建的满包aBag,写伪代码语句,删除并显示包中的所有字符串。

其他的动作并不改变包的内容。其中一个动作是计数包中给定对象的出现次数。我们先用伪代码后用UML说明它,如下所示。

另一个方法测试包是否含有给定对象。使用伪代码和UML给出的规格说明如下所示。

自测题5 给定自测题1中创建的满包aBag,写伪代码语句,找出aBag中字符串"Hello"出现的次数,如果有的话。

最后,我们想看看包的内容。不是提供显示包中项的方法,而是定义一个方法来返回保存这些项的数组。这样,客户可以按照自己的意愿显示部分或全部的项。下面是最后这个方法的规格说明:

当方法返回一个数组时,它通常应该定义一个新的数组来返回。我们还将说明这个方法的细节。
当我们为包中的方法提供前面那些规格说明时,使用UML符号来表示它们。图1-2显示了这些结果。

注意,CRC卡和UML并不反映所有的细节,例如我们在前面的讨论中提到过的假定和特殊情形。但是,在确定了这样的条件后,你应该在每个方法的下面说明该方法应有的动作。
应该写下你的决策,想让方法如何动作,就像我们写在下表中的那样。然后,可以将这些非形式化的描述放在说明方法的Java注释中。


设计决策:当特殊条件出现时会怎样?

作为类的设计者,必须要做出决定如何处理特殊条件,并将这些决策包含在规格说明中。ADT包的文档应该反映这些决策和前面讨论的细节。
一般地,可以用几种方式声明特殊情形。你的方法可能

  • 假定无效的情形不能发生。这个假定并不像听起来那么幼稚。方法可以声明一种假设(即前置条件),这是客户必须遵守的限制。然后由客户检查在方法调用前这个前置条件是否满足。例如,方法remove的前置条件可能是包为非空的。注意,客户可以使用ADT包的其他方法,例如isEmpty和getCurrentSize,来辅助完成这个任务。只要客户遵守这个限制,无效的情形就不会发生。
  • 忽略无效情形。当给出无效数据时方法可能简单到什么也不做。但是什么都不做会让客户不知道发生了什么。
  • 猜测客户的意图。与前一个选择一样,这个选择可能为客户带来麻烦。
    返回一个表示问题的值。例如,如果客户试图从空包中remove一项时,remove方法应该返回null。返回的值必须是不在包中的值。
  • 返回一个布尔值,表示操作的成功或失败。
  • 抛出一个异常。

注:抛出异常经常是Java方法运行期间处理遇到的特殊事件的理想方法。方法可以简单地报告问题而不决定要做什么。异常能让每个客户根据自己的特殊情形按需处理。Java插曲2将介绍异常的基本机制。

注:ADT规格说明的草稿经常忽视或忽略你确实需要考虑的情形。你可能为了简化草稿而有意忽略这些。一旦写好了规格说明中的大部分内容,就可以关注这些细节,而让规格说明更完善。

一个接口

随着规格说明越来越详细,也越发地影响到你对程序设计语言的选择。最终,你可能为包的方法写下Java的方法头并将它们组织为一个Java接口,用它们来实现ADT的类。程序清单1-1中的Java接口含有ADT包的方法及描述它们行为的详细注释。回想一下,类接口不含有数据域、构造方法、私有方法或保护方法。
现在,包中的项将是同一个类的对象。例如,我们可以有字符串的包。为了容纳类类型的项,包的方法中使用泛型数据类型(generic data type)T>来表示每个项。必须在接口名的后面写,来说明标识符T的含义。一旦客户选择了具体的数据类型,编译程序将在T出现的所有地方使用那个数据类型。接在本章后面的Java插曲1中,将讨论如何使用泛型为ADT中的数据提供类型的灵活性。
当检查接口时,注意前一段中提到的处理特殊情形时所做的决策。具体来说,对于add、remove及contains方法,它们每一个都返回一个值。因为我们的程序设计语言是Java,所以要注意,有一个remove方法返回一个指向项的引用,而不是项本身。
虽然不一定要在实现类之前写接口,但这样做能让你以简洁的方式记录你的规格说明。然后可以将接口中的代码用在具体类的框架中。有了接口还能为包提供数据类型,它不依赖于具体的类定义。接下来的两章将开发包类的两种不同的实现。针对接口所写的代码,能让我们更易于将包的一种实现替换为另一种。
程序清单1-1 包类的Java接口

说明一个ADT并为它的操作写了Java接口后,应该写几个使用ADT的Java语句。虽然还不能执行这些语句(毕竟我们没写实现BagInterface的类),但我们可以用它们来确认或者修改方法的设计决策及相关文档。这样,可以检查规格说明的适应性及对它的理解。最好现在来修改ADT的设计或文档,而不是等到写完实现后再进行。认真做这件事的额外好处是,后面可以使用这些相同的Java语句来测试你的实现。

自测题6 给定自测题1创建的包aBag,写Java语句,显示aBag中所有的字符串。不要改变aBag的内容。

程序设计技巧:在实现一个类之前写测试程序

写Java语句来测试一个类的方法,将有助于你完全理解方法的规格说明。很明显,在能正确实现方法之前必须理解它。如果你也是类的设计者,那么使用这个类可能有助于你对设计或对文档进行理想的修改。如果在实现类之前做这些修改,将会节省时间。因为早晚都要写一个程序来测试你的实现,所以为什么不现在写而获益,而非要放到以后再写呢?

注:虽然我们说过,包中的项属于同一个类,但这些项也可能属于因继承关系而相关的类。例如,假定Bag是实现接口BagInterface的类。如果我们写下面的语句创建类C对象的包:

则aBag中可以包含类C的对象及C的任何子类的对象。
下一节看看使用包的两个例子。后面,可以用这些例子来测试你的实现。

时间: 2024-10-02 08:48:43

《数据结构与抽象:Java语言描述(原书第4版)》一1.2 说明一个包的相关文章

《机器学习与R语言(原书第2版)》一2.3 探索和理解数据

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第2章,第2.3节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 2.3 探索和理解数据 在收集数据并把它们载入R数据结构以后,机器学习的下一个步骤是仔细检查数据.在这个步骤中,你将开始探索数据的特征和案例,并且找到数据的独特之处.你对数据的理解越深刻,你将会更好地让机器学习模型匹配你的学习问题. 理解数据探索的最好方法就是通过例子.在

《机器学习与R语言(原书第2版)》一第3章 懒惰学习——使用近邻分类

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第3章,第3.1节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 第3章 懒惰学习--使用近邻分类 一种新型有趣的餐饮体验已经出现在世界各地的城市中,顾客在一个完全黑暗的餐厅里接受服务,而服务员在仅凭触觉和听觉记忆的路上小心地移动.这些餐厅的魅力在于这样的信仰:去掉一个人的视觉感官输入将会增强他的味觉和嗅觉,从而可以使他以一种全新的方式

《机器学习与R语言(原书第2版)》一1.3 机器如何学习

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第1章,第1.3节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 1.3 机器如何学习 机器学习的一个正式定义是由计算机科学家Tom M. Mitchell提出的:如果机器能够获取经验并且能利用它们,在以后的类似经验中能够提高它的表现,这就称为机器学习.尽管这个定义是直观的,但是它完全忽略了经验如何转换成未来行动的过程,当然学习总是说起

《机器学习与R语言(原书第2版)》一1.6 总结

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第1章,第1.6节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 1.6 总结 机器学习起源于统计学.数据库科学和计算机科学的交叉.它是一个强大的工具,能够在大量的数据中找到可行动的洞察.然而,人们仍需持谨慎的态度,避免现实生活中机器学习的普遍滥用. 从概念上讲,机器学习涉及把数据抽象为结构化表示,并把这个结构化表示进行一般化从而推广到

《机器学习与R语言(原书第2版)》一1.5 使用R进行机器学习

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第1章,第1.5节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 1.5 使用R进行机器学习 机器学习所需要的很多算法都没有包含在R的基本安装中.但一个很大社区的专家免费分享他们的机器学习成果,机器学习所需要的算法就是通过这种方式得到.这些必须通过手动方式安装在R基础安装包之上.多亏R是免费的开源软件,没有为这种功能额外收费.那些能在用

《机器学习与R语言(原书第2版)》一 第2章 数据的管理和理解

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第2章,第2.1节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 第2章 数据的管理和理解 任何机器学习项目初期的核心部分都是与管理和理解所收集的数据有关的.尽管你可能发现这些工作不像建立和部署模型那样令人有成就感(建立和部署模型阶段就开始看到了劳动的成果),但是忽视这些重要的准备工作是不明智的.任何学习算法的好坏取决于输入数据的好坏.

机器学习与R语言(原书第2版)》一1.4 实践中的机器学习

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第1章,第1.4节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 1.4 实践中的机器学习 到目前为止,我们已经讲述了理论上机器学习是如何工作的.为了把机器学习应用到真实世界的任务中,我们将采用由5个步骤构成的过程.不管你手头是何种任务,任何机器学习算法都能由下面这些步骤来实施:1)数据收集:数据收集步骤包括收集算法用来生成可行动知识的

《机器学习与R语言(原书第2版)》一2.2 用R管理数据

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第2章,第2.2节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 2.2 用R管理数据 当处理大量数据集时,面临的挑战包括收集.准备和管理来自各种不同来源的数据.尽管通过学习后面章节中的真实世界的机器学习任务,我们会深入地涉及数据准备.数据清理和数据管理,但本节重点讲述基本的R数据导入和导出功能. 2.2.1 保存.载入和移除R数据结构

《机器学习与R语言(原书第2版)》一 第1章 机器学习简介

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第1章,第1.1节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 第1章 机器学习简介 如果科幻故事是可信的,那么人工智能的发明将会不可避免地导致机器和其制造者之间的末日战争.在计算机使用的早期,计算机被教会玩井字棋和国际象棋这样一些简单的游戏.后来,机器被用来控制交通信号灯和通信,随后用来控制军用无人机和导弹.一旦计算机有感知力并且知

《机器学习与R语言(原书第2版)》一2.4 总结

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第2章,第2.4节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 2.4 总结 在本章中,我们学习了在R中管理数据的基础.从深入剖析用来存储不同类型数据的数据结构开始.R数据的基本结构是向量,它扩展和组合成更复杂的数据结构,比如,列表和数据框.数据框是与数据集概念相联系的R数据结构,数据框内同时有特征和案例.R提供了从电子表格类的数据文