抽象函数(Java)

2023-11-18

我们现在深入理解一下抽象数据类型背后的理论,这些理论不仅本身很有趣,它们在ADT的设计与实现中也很有意义。如果你能够很好的理解它们,你将会设计出更好的抽象类型,并且远离那些隐晦的陷阱。

在研究抽象类型的时候,先思考一下两个值域之间的关系:

表示域(space of representation values)里面包含的是值具体的实现实体。在简单的情况下,一个抽象类型只需要实现为单个的对象,但是更常见的情况是使用一个很多对象的网络。

抽象域里面包含的则是类型设计时支持使用的值。这些值是由表示域“抽象/想象”出来的,也是使用者关注的。例如,一个无限整数对象的抽象域是整个整数域,但是它的实现域可能是一个由原始整数类型(有限)组成的数组实现的,而使用者只关注抽象域。

但是,实现者是非常“在意”表示域(和抽象域)的,因为实现者的责任就是实现表示域到抽象域的转换(映射)。

例如,我们选择用字符串来表示一个字符集合:

public class CharSet {
    private String s;
    ...
}

在这里插入图片描述
如上图所示,表示域R包含的是我们的实现实体(字符串),而抽象域里面是抽象类型表示的字符集合,我们用箭头表示这两个域之间的映射关系。这里要注意几点:

·每一个抽象值都是由表示值映射而来 。我们之前说过实现抽象类型的意义在于支持对于抽象值的操作,即我们需要能够创建和管理所有的抽象值,因此它们也必须是可表示的。
·一些抽象值是被多个表示值映射而来的。这是因为表示方法并不是固定的,我们可以灵活的表示一个抽象值。
·不是所有的表示值都能映射到抽象域中。在上面这个例子中,“abbc”就没有被映射。因为我们已经确定了表示值的字符串中不能含有重复的字符——这样我们的 remove 方法就能在遇到第一个对应字符的时候停止,因为我们知道没有重复的字符。
由于我们不可能对每一个映射一一解释,为了描述这种对应关系和这两个域,我们再定义两个概念:

抽象函数abstraction function是表示值到其对应的抽象值的映射:
AF:R->A
快照图中的箭头表示的就是抽象函数,可以看出,这种映射是满射,但不一定是单射(不一定是双射)。

表示不变量rep invariant是表示值到布尔值的映射:
RI:R->boolean
对于表示值r,当且仅当r被AF映射到了A,RI®为真。换句话说,RI告诉了我们哪些表示值是“良好组织”的(能够去表示A中的抽象值),在下图中,绿色表示的就是RI®为真的部分,AF只在这个子集上有定义。
在这里插入图片描述
例如上图中,CharSet这种类型的实现禁止有重复字符,所以 RI(“a”) = true, RI(“ac”) = true, RI(“acb”) = true, 但是 RI(“aa”) = false, RI(“abbc”) = false.其中为假的集合用红色区域表示,合法的(为真)的字符串集合用绿色表示。

表示不变量和抽象函数都应该在表示声明后注释出来:

public class CharSet {
    private String s;
    // Rep invariant:
    //   s contains no repeated characters
    // Abstraction function:
    //   AF(s) = {s[i] | 0 <= i < s.length()}
    ...
}

一个常见的疑惑就是,抽象函数和表示不变量似乎是被表示域和抽象域决定的,甚至似乎抽象域就可以决定它。如果是这样的话,那么它们的定义似乎没什么用。

首先证明抽象域并不能独立决定AF和RI:对于同样的抽象类型可以有多种表示方法。例如对于一个字符集合,我们既可以用字符串来表示,也可以用比特向量来表示,每一个比特位对应一个可能的字符。显然我们需要两个不同的抽象函数来表示这两种不同的映射。

现在我们再来证明表示域和抽象域也不能决定AF和RI。这里的关键点在于,当我们确定表示域(表示值的空间)后,我们并不能决定哪一些表示值是合法的,以及如果它是合法的,它会被怎么解释/映射。例如在上面的例子中,我们也可以允许表示值有重复的字符,但是我们要求表示值中的字符必须是排好序的,因为这样我们就可以对其进行二分查找而非线性的遍历了。对于同一个表示域,我们得到了不同的表示不变量:
在这里插入图片描述

public class CharSet {
    private String s;
    // Rep invariant:
    //   s[0] <= s[1] <= ... <= s[s.length()-1]
    // Abstraction function:
    //   AF(s) = {s[i] | 0 <= i < s.length()}
    ...
}

最后,即使是同样的抽象域和表示域以及同样的表示不变量,我们也可能有不同的解释方法/抽象函数。还是上面的例子,我们可以对表示值中相邻的字符做不同的解释: “acgg” 被解释为[a-c] 和 [g-g]中的字符,即{a,b,c,g}。现在的映射如下图所示:
在这里插入图片描述

public class CharSet {
    private String s;
    // Rep invariant:
    //   s.length() is even
    //   s[0] <= s[1] <= ... <= s[s.length()-1]
    // Abstraction function:
    //   AF(s) = union of { c | s[2i] <= c <= s[2i+1] } 
    //           for all 0 <= i < s.length()/2
    ...
}

总之,一个ADT的实现不仅是选择表示域(规格说明)和抽象域(具体实现),同时也要决定哪一些表示值是合法的(表示不变量),合法表示会被怎么解释/映射(抽象函数)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

抽象函数(Java) 的相关文章

  • 【Linux学习笔记】7. Linux文件IO详解(附代码实例)

    Linux文件I O 前置知识 Linux文件I O分为系统IO和标准IO 常用于系统编程 系统I O通过文件描述符 fd 来操作文件 标准I O通过文件流 FILE 来操作文件 Linux下可以使用man命令来查看使用手册 学习和使用这些
  • 数据备份技术知识梳理(建议收藏)

    所谓数据保护技术是指对当前时间点上的数据进行备份 如果说原始数据被误删除了 可以通过备份数据找回或恢复数据 从底层来分 数据保护可以分为文件级保护和块级保护 文件级备份 文件级备份 将磁盘上所有文件通过调用文件系统接口备份到另一个介质上 也
  • 11-7 读写指定大小的字节

    1 字节 一个字节 8 位 例如在 ASCII 码表中 0000 1010 表示换行 若从十六进制角度看 则结果为 0a CLion debug 便是以十六进制查看的字节 2 读字节 fread 函数用于指定字节大小的读取 该函数可读取二进
  • 重启大法好

    在做springMVC服务器的时候 出现解析不了URL 即dispatch映射不了action的时候 1 检查springname servlet xml 2 检查web xml 3 检查注解是否错误 4 重启eclipse 5 重启电脑
  • Unity3D射线检测

    射线检测主要用于像子弹是否打中物体 捡取物品等情况 本来面向百度想找例子看看 不过没找到合适的 还是自己总结尝试吧 以下测试Unity3D版本 2017 4 2f2 射线的检测步骤如下 1 Ray 这个类为了产生一个射线 如果我们想要场景中
  • Acwing 906. 区间分组

    1 将所有区间按照左端点从小到大排序 2 从前往后处理每个区间 判断能否将其放到某个现有的组中 L i gt Max r 1 如果不存在这样的组 则开新组 然后将其放进去 2 如果存在这样的组 将其放进去 并更新当前组的Max r incl
  • cocoscreator 3.x 获取像素颜色

    const pos v2 世界坐标 const color as camera rt targetTexture readPixels pos v2 x pos v2 y 1 1 获得颜色 cc color color as 0 color
  • BeautifulSoup4(bs4)

    BeautifulSoup4是一个高效的网页解析库 可以从HTML或XML文件中提取数据 支持不同的解析器 比如 对HTML解析 对XML解析 对HTML5解析 就是一个非常强大的工具 爬虫利器 一个灵感又方便的网页解析库 处理高效 支持多
  • java 枚举应用_Java枚举应用

    JDK5 0开始引进了java Enum枚举类型 它可作为我们在编写代码时的一个技巧 有时恰恰因为它 我们能够 优雅而干净 地解决问题 在使用枚举类型时 我们所编写的枚举类都是隐式地继承于java lang Enum类 枚举类的每个成员都被
  • 报错:ImportError: XXXX.so:invalid ELF header

    运行程序遇到如下报错 原因是该路径下的 so文件与运行程序的环境不匹配 比如我在mac电脑上编译生成的 so文件 直接放到linux服务器上跑了 自然会有错误 解决的方法是在Linux环境中重新编译生成新的 so文件
  • C语言非常道 6.7

    使用结构类型 计算结构类型的大小 在上面这个程序中包含一个输入输出的头文件即可 这个位置又发现一个问题 在定义结构体的时候 数组的大小是一定要标明的 否则在计算结构体大小的时候 编译无法通过
  • C/C++ 安全编码 —— 指针与内存

    1 仿踩内存 if buf len 1 0x5A return
  • Node.js开发入门—HTTP文件服务器

    HelloWorld示例只有演示意义 这次我们来搞一个实际的例子 文件服务器 我们使用Node js创建一个HTTP协议的文件服务器 你可以使用浏览器或其它下载工具到文件服务器上下载文件 用Node js实现的HTTP文件服务器 比我在Qt
  • iOS、mac开源项目及库

    1 用来生成 3x 的图片资源对应的 2x 和 1x 版本 只要拖拽高清图到 3x 的位置上 然后按 Ctrl Shift A 即可自动生成两张低清的补全空位 当然你也可以从 2x 的图生成 3x 版本 如果你对图片质量要求不高的话 htt
  • 深入理解操作系统原理之文件系统

    一 概述 操作系统对系统的软件资源 不论是应用软件和系统软件 的管理都以文件方式进行 承担这部分功能的操作系统称为文件系统 1 文件 计算机系统对系统中软件资源 无论是程序或数据 系统软件或应用软件都以文件方式来管理 文件是存贮在某种介质上
  • flink 1.4版本flink table方式消费kafka写入hive方式踩坑

    最近在搞flink 搞了一个当前比较新的版本试了一下 当时运行了很长时间 hdfs里面查询有文件 但是hive里面查询这个表为空 后面用了很多种方式 一些是说自己去刷新hive表 如下 第一种方式刷新 alter table t kafka
  • win10 下 python连接读取hive,报错No protocol version header

    impyla 依赖的thriftpy2包的相关报错 1 No protocol version header 找到对应位置注释掉该报错的代码 if strict raise TProtocolException type TProtocol
  • java.lang.ClassNotFoundException: Didn't find class "android.support.v4.app.CoreComponentFactory"

    android9报错 java lang ClassNotFoundException Didn t find class android support v4 app CoreComponentFactory
  • css 样式实战

    css实战目录 一 纯css 控制 布局等分 2 1 3 1 position 定位 input 只展示下边线 input textarea placeholder 提示 的颜色 input 输入框增加 搜索图标 1 input 输入框增加
  • 解决Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘id‘)报错

    项目场景 做黑马的人资项目时 要读取store中的userInfo里的id值 报Uncaught in promise TypeError Cannot read properties of undefined reading id 错 起

随机推荐

  • python笔记:python的优点

    pyhon语言的优点 1 简单易用 2 提供了大量的功能类库 3 python具有语言兼容性 4 具有跨系统移植能力 5 代码免费开源
  • 大数据入门——搜索广告的文本点击率预估(python实现)2019高校大数据挑战赛

    大数据入门 搜索广告的文本点击率预估 python实现 顺便解决gensim包导入错误 ImportError DLL load failed 找不到指定的模块 文本点击率预估 概念解释 思路分析 具体步骤 一 工具 原料 gensim包的
  • FreeBSD ssh 忘记密码

    一 freeBSD的两种破解密码方法 这两种方法是我亲自验证过的 第一种 1 开机进入引导菜单 2 选择每项 按4 进入单用户模式 4 boot frebsd in single user mode 进入后看到 Enter full pat
  • android sqlite 升级数据库 修改表名, 增加字段,修改字段类型

    升级数据库 注意 修改数据库后 一定要记得增加数据库版本号 1 否则不会走onUpgrade方法 最残暴的方法 Override public void onUpgrade SQLiteDatabase db int oldVersion
  • Vue监听不到对象属性的变化 解决方法

    方法一 通过vue的this set object key value 没试过 方法二 通过Object assign 重新创建一个对象 例如this someObject Object assign this someObject a 1
  • 使用PHP发送邮件的两种方法

    今天研究了一下使用PHP来发送电子邮件 总结了一下 有这么两种方法 一 使用PHP内置的mail 函数 看了一下手册 就直接开始写代码了 如下
  • docker 安装 mysql (windows版本)

    docker 安装 mysql windows版本 1 下载 MySQL 社区版映像 运行以下命令 docker pull mysql mysql server 5 7 2 启动Docker容器 请使用以下命令 docker run nam
  • 第一行代码——第五章:全局大喇叭——详解广播机制

    目录 5 1 广播机制简介 5 2 接收系统广播 5 2 1 动态注册监听网络变化 5 2 2 静态注册实现开机启动 5 3 发送自定义广播 5 3 1 发送标准广播 5 3 2 发送有序广播 5 4 使用本地广播 5 5 广播最佳实践 实
  • 一文掌握 MobileNetV3 在 TorchVision 中的实现细节

    TorchVision v0 9 中新增了一系列移动端友好的模型 可用于处理分类 目标检测 语义分割等任务 本文将深入探索这些模型的代码 分享值得注意的实现细节 解释这些模型的配置和训练原理 并解读模型优化过程中官方做出的重要权衡 本文的目
  • Linux Redis-v6.2.7的安装与配置

    Redis v6 2 7的安装与配置 官网下载页地址 1 下载 解压 编译安装 wget https download redis io releases redis 6 2 7 tar gz cp redis 6 2 7 tar gz u
  • localhost: Error: JAVA_HOME is not set. [Hadoop] Error: JAVA_HOME is not set

    localhost Error JAVA HOME is not set 在namenode启动脚本 Hadoop HOME bin start dfs sh的时候发现datanode报错 Error JAVA HOME is not se
  • 非确定性算法_近似算法

    晓强Deep Learning的读书分享会 先从这里开始 从大学开始 大家好 我是晓强 计算机科学与技术专业研究生在读 我会不定时的更新我的文章 内容可能包括深度学习入门知识 具体包括CV NLP方向的基础知识和学习的论文 网络表征学习的相
  • Pycharm无法正常安装第三方库的时候,有以下几条应对方法

    1 首先检查自己的环境变量是否配置正确 点击setting 点击 Python Interpreter 点击Add Interpreter 找到这个界面 点击右方三个点 然后选择正确的python安装位置 点击OK 配置完毕之后再试一次从这
  • android轮播图实现方案,Android轮播图实现教程

    ListView的headerView设置为轮播图之后结合上 下拉刷新 加载的模式成为现在大多数APP的一个必须具备的功能 对于许多初学者来说想要实现轮播图这样一个集线程睡眠 自动处理 替换过程中刷新UI界面的组合功能非常困难 没有思路 感
  • 实验吧 web题--代码审计类

    一 因缺思汀的绕过 1 web题常规套路就是查看源代码 于是右击查看源代码发现 br 构造url http ctf5 shiyanbar com web pcat source txt 查看php代码 2 关键php代码 if mysql
  • [HashMap源码学习之路]---put方法中的hash方法介绍

    HashMap中的put方法中的hash方法 以下是put方法的代码 public V put K key V value return putVal hash key key value false true 当我第一次看到这个地方的时候
  • 2022年,能让你月入过万的5个副业,不信试试

    2021年已经过去了 不管过去的一年 是成功还是失败 一切都过去了 新的一年要开始做新的规划 当务之急 搞钱最为重要 01 自媒体写作 以前我总是觉得会写文章不算什么技能 工作之后才发现 文字功底好优势好大 无论是工作还是做副业 发现会写文
  • 10.29奇偶交换排序

    奇偶交换排序如下所述 第一趟对所有奇数i 将a i 和a i 1 进行比较 第二趟对所有的偶数i 将a i 和a i 1 进行比较 若a i gt a i 1 则将两者交换 第三趟对奇数i 第四趟对偶数i 依次类推直至整个序列有序为止 in
  • Flask 学着用模板 render_template

    上一章节是做到了在本地浏览器上打印出hello world 如果你要更加复杂 可以像下面一样在return结果里添加内容 但是 简单的几句话你可以这么写 要是整的一个网页 你可没法把代码都拖在return后面吧 所以 后面引入了模板功能 模
  • 抽象函数(Java)

    我们现在深入理解一下抽象数据类型背后的理论 这些理论不仅本身很有趣 它们在ADT的设计与实现中也很有意义 如果你能够很好的理解它们 你将会设计出更好的抽象类型 并且远离那些隐晦的陷阱 在研究抽象类型的时候 先思考一下两个值域之间的关系 表示