Microsoft PowerPoint - plan08.ppt



Similar documents
(procedure-oriented)?? 2

Microsoft PowerPoint - plan06.ppt

<4D F736F F F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

Microsoft Word - 物件導向編程精要.doc

Chapter 9: Objects and Classes

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

文档 3

FY.DOC

Microsoft Word - ch04三校.doc

Strings


電機工程系認可證照清單 /7/1

黄 永 润 带 队 参 加 市 场 营 销 与 物 流 管 理 培 训 班... 6 黄 永 润 出 席 茶 业 集 团 春 茶 生 产 经 营 分 析 会... 6 大 明 山 茶 文 化 生 态 家 园 项 目 签 约 仪 式 在 邕 举 行... 7 广 西 职 业 技 术 学 院 开 展 庆

中山市**局2005年部门预算基本情况说明


<4D F736F F D203234A8E2A9A4B142ABC3AABAB7C5B1A1ADB1BB50AA6BA8EEADB1>

机动车驾驶证申领和使用规定(公安部令第91号)

<4D F736F F D20A2B0A1D0A2B0A1D0A2B0A240A6CBAA4FC554BC4DB7ABA240A7D6AA4FBD6DB2DF2E646F63>

Microsoft Word 薪酬管理制度.doc

利 润 预 计 为 360, 万 元 ; 假 设 2016 年 归 属 母 公 司 所 有 者 的 净 利 润 较 2015 年 度 预 测 值 的 基 础 上 增 长 15%, 为 414, 万 元 上 述 利 润 值 不 代 表 公 司 对 未 来 利 润 的 盈 利 预

0660

<4D F736F F D203033C8ABC8D5D6C6B1BEA1A2D7A8BFC6C9FAD1A7B7D6D6C6D1A7BCAEB9DCC0EDB9E6B6A82E646F63>

黄 河 两 岸 耸 立 着 万 丈 高 山 战 士 们 站 在 河 畔 仰 起 头 看, 天 像 一 条 摆 动 的 长 带 子 人 要 站 在 河 两 岸 的 山 尖 上, 说 不 定 云 彩 就 从 耳 边 飞 过, 伸 手 也 能 摸 着 冰 凉 的 青 天 山 峡 中, 浑 黄 的 河 水

Microsoft Word - 雲林縣學校轉型優質計畫.docx

<4D F736F F D20BDADCBD5CAA1B9A9CFFABACFD7F7D7DCC9E7BCF2B1A8B5DA3239C6DA2E646F63>

<4D F736F F D20C3F1D3C3BBFAB3A1BDA8C9E8B9DCC0EDB9E6B6A8B7A2B2BCB8E52E646F63>

慈宗彌勒淨土法門的殊勝

5.1施工企业会计核算办法

論文全.doc

专科疾病诊治(十二)


untitled



Az b.doc

文档2

Microsoft PowerPoint ShengYang Presentation Slides_240609

Microsoft Word - 1-3陳詠琳-近代..

第 15 章 程 式 編 写 語 言 15.1 程 式 編 写 語 言 的 角 色 程 式 編 寫 語 言 是 程 式 編 寫 員 與 電 腦 溝 通 的 界 面 語 法 是 一 組 規 則 讓 程 式 編 寫 員 將 字 詞 集 合 起 來 電 腦 是 處 理 位 元 和 字 節 的 機 器, 與

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

1.5招募说明书(草案)

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

c_cpp

Microsoft Word - chap10.doc

untitled

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

Chapter12 Derived Classes

30.00% 25.00% 25.00% 22.50% 20.00% 15.00% 12.50% 15.00% 12.50% 10.00% 7.50% 5.00% 2.50% 2.50% 0.00% 文 学 理 学 工 学 法 学 教 育 学 管 理 学 历 史 学 艺 术 学 ( 三 ) 学 生

Microsoft PowerPoint - L17_Inheritance_v4.pptx

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

新・解きながら学ぶJava


IoC容器和Dependency Injection模式.doc

1 C++ 2 Bjarne Stroustrup C++ (system programming) 6 (infrastructure) C++ 7 Herb Sutter 8 C++ (efficiency) (flexibility) 9 (abstraction) (productivity

untitled

“百企入校——广西青年企业家协会高校

摘 要 本 校 多 媒 體 設 計 系 與 上 海 戲 劇 學 院 創 意 學 院 在 多 次 聯 繫 交 流 之 下, 已 簽 署 合 作 備 忘 錄, 積 極 尋 求 兩 校 合 作 教 學 與 共 同 創 作 之 機 會 藉 由 本 系 學 生 作 品 腦 殘 公 寓 入 圍 第 五 屆 中

國家圖書館典藏電子全文

Java

股东大会材料2.PDF

untitled

用户大会 论文集2.2.doc

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

第 一 部 分 前 言 研 究 前 言 : 楊 逵 是 臺 灣 文 學 史 上 一 位 不 可 或 缺 的 重 要 作 家 他 的 文 學 作 品, 不 論 是 小 說 詩 歌 或 是 戲 劇 等, 都 有 著 相 當 的 社 會 影 響 力 為 深 入 瞭 解 這 位 文 學 巨 人 的 作 品,


untitled

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

EJB-Programming-3.PDF

本 课 程 作 为 非 计 算 机 专 业 本 科 通 识 课 程, 是 一 门 理 论 和 实 践 紧 密 结 合 的 实 用 课 程, 内 容 包 括 计 算 机 基 础 部 分 和 程 序 设 计 部 分 计 算 机 基 础 部 分 涵 盖 计 算 机 软 硬 件 组 成 数 制 表 示 操


JBuilder Weblogic

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

untitled

Chapter 9: Objects and Classes

untitled

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

Az b.PDF

D C 93 2

第一编 文明之前的人类

❶ 前 言 你 快 樂 嗎? 你 睡 得 好 嗎? 是 否 心 裡 總 是 有 股 揮 之 不 去 的 煩 悶 或 憂 鬱? 是 否 很 難 放 自 己 一 馬? 不 知 道 怎 麼 愛 自 己? 壓 力 可 以 是 生 病 的 原 因, 也 可 以 是 成 長 的 動 力 如 何 面 對 你 內

untitled

Microsoft Word - chap13.doc


untitled

epub83-1

extend

Microsoft Word - ch01.doc

Wy159.mps

《大话设计模式》第一章

Az b.doc

ndbg217.PDF

ebook55-13

基于CDIO一体化理念的课程教学大纲设计

? (1) (2) (3) (IS) IS 650 信息技术教程 ( 第 7 版 )

提问袁小兵:

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

前言

<4D F736F F D20CAD9C3FCCAC7D7D4BCBAD2BBB5E3D2BBB5CEC5ACC1A6C0B4B5C4A1AAA1AA41342E646F63>

Transcription:

程 序 设 计 语 言 原 理 Principle of Programming Languages 裘 宗 燕 北 京 大 学 数 学 学 院 2012.2~2012.6 8. 面 向 对 象 为 什 么 需 要 面 向 对 象? OO 语 言 的 发 展 面 向 对 象 的 基 本 概 念 封 装 和 继 承 初 始 化 和 终 结 处 理 动 态 方 法 约 束 多 重 继 承 总 结 2012 年 5 月 2

重 用 的 问 题 实 践 中 人 们 认 识 到 重 用 已 有 开 发 结 果 的 重 要 性, 提 出 了 软 件 重 用 的 概 念 最 早 的 重 用 单 元 是 子 程 序, 如 Fortran 的 子 程 序 库 子 程 序 是 纯 粹 的 过 程 抽 象, 基 于 子 程 序 的 重 用 有 很 大 局 限 性 模 块 是 更 合 适 的 重 用 单 元, 因 为 模 块 可 以 包 装 任 何 功 能, 更 灵 活 重 用 中 有 一 种 常 见 情 况 : 软 件 开 发 中 遇 到 的 新 问 题 常 与 解 决 过 的 问 题 ( 可 以 重 用 的 库 提 供 的 功 能 ) 类 似, 但 又 不 完 全 相 同 已 有 模 块 的 功 能 与 需 要 有 差 异, 无 法 以 其 现 有 形 式 直 接 使 用 如 果 模 块 功 能 的 改 变 只 能 通 过 修 改 源 代 码 的 方 式 进 行, 程 序 员 就 只 能 拷 贝 这 个 模 块 的 源 代 码, 深 入 研 究 后 再 设 法 修 改, 以 满 足 新 需 求 但 问 题 是 有 没 有 可 以 使 用 的 源 代 码? 常 常 没 有 : 模 块 可 能 是 购 入 的, 提 供 商 不 提 供 源 代 码 模 块 可 能 是 过 去 的 遗 产, 源 代 码 已 经 丢 失 或 部 分 缺 失 2012 年 5 月 3 重 用 和 软 件 开 发 即 使 有 源 代 码, 基 于 修 改 代 码 的 方 式 重 用, 也 有 很 多 问 题 : 修 改 代 码 的 代 价 可 能 很 大 ( 需 要 理 解 开 发 者 的 想 法 设 计 和 大 量 细 节 ) 修 改 代 码 很 容 易 引 进 错 误 经 过 修 改 的 代 码, 其 可 读 性 易 理 解 性 和 易 维 护 性 都 会 恶 化, 多 次 修 改 导 致 这 些 性 质 不 断 恶 化, 可 能 给 整 个 系 统 的 质 量 带 来 严 重 危 害 修 改 后 的 模 块, 继 续 重 用 的 可 能 性 更 小 总 之, 基 于 修 改 代 码 的 重 用, 重 用 的 价 值 大 大 降 低 了 在 软 件 开 发 过 程, 重 用 也 是 非 常 有 价 值 的 在 同 一 软 件 中 重 复 使 用 某 些 部 分, 可 使 重 要 设 计 决 策 得 到 集 中 处 理 提 高 重 用 比 率 可 能 减 少 重 复 开 发 工 作 量 对 重 要 基 础 功 能 的 深 度 优 化 可 能 非 常 耗 工 耗 时, 重 用 已 有 的 经 过 精 心 调 整 的 代 码, 可 能 大 大 提 高 系 统 的 性 能 2012 年 5 月 4

模 块 和 程 序 组 织 常 规 的 程 序 单 元 缺 乏 弹 性, 定 义 好 的 子 程 序 / 模 块 都 是 固 定 功 能 的 实 体, 难 以 提 供 定 制 的 方 式 部 分 地 改 变 功 能 以 满 足 实 际 需 要 的 变 化 通 过 模 块 定 义 的 抽 象 数 据 类 型 是 相 互 独 立 的, 不 同 模 块 之 间 无 任 何 关 系 而 实 际 情 况 中, 常 常 需 要 定 义 和 使 用 一 些 相 互 有 关 的 类 型, 可 能 需 要 把 它 们 送 给 同 一 个 函 数 / 过 程 去 处 理, 以 同 样 方 式 存 储 变 体 和 联 合 机 制 就 是 为 了 迎 合 这 方 面 的 需 要, 但 它 们 没 有 类 型 安 全 性, 且 未 能 提 供 解 决 类 似 问 题 的 统 一 框 架, 难 用 于 应 付 更 复 杂 的 情 况 支 持 相 关 类 型, 可 能 给 程 序 的 结 构 组 织 带 来 新 的 可 能 性 如 何 在 抽 象 数 据 类 型 的 框 架 中 提 供 这 一 类 功 能, 也 是 需 要 解 决 的 问 题 面 向 对 象 的 概 念 在 这 些 方 面 都 能 发 挥 很 大 的 作 用 面 向 对 象 (Object-Oriented) 的 方 法 和 程 序 技 术, 为 基 于 模 块 ( 一 个 类 也 可 以 看 作 一 个 模 块 ) 的 重 用 问 题 提 供 了 一 条 解 决 途 径 2012 年 5 月 5 面 向 对 象 和 重 用 面 向 对 象 技 术 的 最 重 要 能 力, 在 于 使 程 序 员 比 较 容 易 以 一 种 外 部 附 加 的 方 式, 在 已 有 数 据 抽 象 的 基 础 上 定 义 新 的 数 据 抽 象 OO 也 支 持 定 义 有 弹 性 的 操 作 框 架, 使 新 的 数 据 抽 象 可 以 使 用 这 些 框 架, 并 把 针 对 该 类 抽 象 的 实 例 的 具 体 操 作 插 入 框 架 中 ( 重 用 和 调 整 ) 新 定 义 的 抽 象 可 以 继 承 原 有 抽 象 的 行 为, 也 可 以 根 据 需 要 调 整 改 变 已 有 功 能 的 行 为, 或 者 添 加 新 抽 象 所 需 要 的 新 行 为 这 样 大 大 提 高 了 代 码 重 用 的 可 能 性 ( 目 标 是 实 现 真 正 不 加 修 改 的 重 用 当 然, 实 际 的 重 用 可 能 性 还 与 具 体 数 据 抽 象 的 设 计 有 关 ) 面 向 对 象 还 有 另 外 的 许 多 重 要 价 值 ( 有 些 可 能 同 样 重 要 或 更 重 要 ), 并 由 此 发 展 出 面 向 对 象 的 系 统 分 析, 面 向 对 象 的 设 计 等 面 向 对 象 思 想 对 于 软 件 领 域 的 影 响 是 全 面 的, 是 结 构 化 思 想 ( 结 构 化 程 序 设 计, 结 构 化 分 析, 结 构 化 设 计 等 ) 之 后 软 件 开 发 领 域 中 的 又 一 次 革 命 注 意 : 面 向 对 象 并 没 有 取 代 结 构 化, 应 该 看 作 是 在 另 一 层 次 上 的 抽 象 2012 年 5 月 6

OO 发 展 史 OO 技 术 和 思 想 中 的 一 个 基 本 方 面 是 数 据 和 操 作 的 封 装 这 方 面 的 基 本 想 法 : 一 组 数 据 与 关 联 之 上 相 关 的 操 作 形 成 一 个 对 象 其 内 部 数 据 构 成 对 象 的 状 态, 操 作 确 定 对 象 与 外 界 交 互 的 方 式 OO 并 不 是 从 模 块 化 程 序 设 计 发 展 出 来 的, 它 有 自 己 的 发 展 历 程 OO 的 思 想 与 模 块 化 的 思 想 是 并 行 发 展, 一 直 相 互 影 响 相 互 借 鉴 Simula 67 是 OO 概 念 的 鼻 祖, 其 设 计 目 标 是 扩 充 Algol 60, 以 更 好 地 支 持 计 算 机 在 模 拟 方 面 的 应 用 1960 年 代 在 挪 威 计 算 中 心 设 计 和 实 现, 主 持 其 工 作 的 Ole-Johan Dahl 和 Kristen Nygaard 获 得 2001 年 图 灵 奖 OO 的 三 个 基 本 要 素 : 封 装 继 承 和 动 态 方 法 约 束 都 源 于 Simula 类 的 概 念 源 自 Simula, 其 设 计 中 提 出 用 类 定 义 把 一 组 操 作 与 一 组 数 据 包 装 起 来 Simula 的 这 些 重 要 想 法 是 模 块 概 念 和 OO 的 起 源 Simula 只 提 供 了 基 本 封 装, 并 没 有 对 封 装 的 保 护, 也 没 有 信 息 隐 藏 2012 年 5 月 7 OO 发 展 史 软 件 实 践 也 需 要 OO 的 思 想, 并 逐 渐 开 发 了 相 关 的 支 撑 技 术, 包 括 : 封 装 的 思 想 在 面 向 模 块 的 语 言 里 发 展, 提 出 了 许 多 重 要 概 念 和 想 法, 如 作 用 域 规 则, 开 的 或 者 闭 的 作 用 域 界 面 与 实 现 透 明 类 型 与 隐 晦 类 型, 访 问 控 制, 等 等 数 据 驱 动 的 程 序 设 计 技 术 : 将 计 算 功 能 ( 子 程 序 ) 约 束 于 程 序 里 处 理 的 数 据 ( 结 构 ), 使 我 们 在 程 序 里 可 以 从 数 据 对 象 出 发 去 启 动 相 应 的 计 算 过 程 在 一 些 非 常 规 的 语 言 ( 如 函 数 式 语 言 ) 里, 可 以 通 过 引 用 的 概 念 提 供 函 数 / 过 程 与 数 据 之 间 的 约 束 常 规 语 言 ( 如 C) 引 进 了 指 向 函 数 的 指 针, 在 实 现 数 据 驱 动 程 序 设 计 的 过 程 中 起 到 了 重 要 作 用, 也 成 为 面 向 对 象 语 言 实 现 的 技 术 基 础 2012 年 5 月 8

OO 发 展 史 继 承 和 动 态 约 束 等 被 Smalltalk 发 展, 形 成 目 前 OO 的 基 本 概 念 框 架 程 序 里 以 类 的 方 式 定 义 各 种 数 据 抽 象 类 可 以 通 过 继 承 的 方 式 扩 充 新 功 能, 这 样 定 义 的 新 类 ( 子 类, 派 生 类 ) 自 动 继 承 已 有 类 ( 基 类, 超 类, 父 类 ) 的 功 能 对 象 是 类 的 实 例, 是 程 序 运 行 时 的 基 本 数 据 单 元 派 生 类 的 对 象 也 看 作 是 原 有 基 类 的 对 象, 可 以 当 作 基 类 的 对 象 使 用 ( 子 类 就 是 子 类 型,Liskov 代 换 原 理,2008 年 图 灵 奖 ) 类 定 义 了 对 象 的 状 态 成 分 ( 数 据 成 员 ) 和 一 组 相 关 操 作 ( 称 为 方 法 ) 方 法 调 用 总 是 针 对 某 个 对 象 进 行 的, 将 方 法 调 用 看 作 是 给 相 应 对 象 送 一 个 消 息, 对 象 通 过 执 行 相 应 操 作 的 方 式 对 消 息 做 出 响 应 对 一 个 消 息 执 行 什 么 方 法, 由 接 收 消 息 的 对 象 的 类 型 确 定 ( 根 据 该 对 象 所 属 的 类 确 定, 这 就 是 动 态 约 束 ) 计 算, 就 是 一 组 对 象 相 互 通 讯 的 整 体 效 果 ( 对 计 算 的 另 一 种 看 法 ) 2012 年 5 月 9 OO 发 展 史 Smalltalk 还 有 一 些 独 特 的 东 西 : 变 量 采 用 引 用 模 型, 变 量 无 类 型, 可 以 引 用 任 何 对 象 语 言 里 的 一 切 都 是 对 象 : 类 也 是 对 象, 通 过 给 类 送 new 消 息 的 方 式 要 求 创 建 类 的 实 例 各 种 控 制 结 构 也 是 通 过 消 息 概 念 建 立 的 o 条 件 和 逻 辑 循 环 是 逻 辑 对 象 对 特 定 消 息 的 响 应 o 枚 举 循 环 是 整 数 对 象 对 特 定 消 息 的 响 应 采 用 单 根 的 类 层 次 结 构, 以 类 Object 作 为 所 有 类 的 超 类 提 供 了 块 (block) 的 概 念, 作 为 控 制 结 构 的 抽 象 机 制 提 出 了 容 器 的 概 念, 开 发 了 一 个 功 能 丰 富 的 类 库 与 程 序 开 发 环 境 的 紧 密 结 合, 并 开 发 了 GUI 的 基 本 概 念 和 相 关 技 术 Smalltalk 经 过 72 76 发 展 到 Smalltalk 80, 其 概 念 和 结 构 已 臻 成 熟 2012 年 5 月 10

OO 发 展 史 随 着 Smalltalk 的 成 功, 人 们 看 到 了 OO 的 潜 在 威 力 许 多 人 开 始 研 究 如 何 把 OO 概 念 有 效 集 成 到 常 规 语 言 里, 提 出 了 一 批 已 有 语 言 的 OO 扩 充 和 许 多 新 OO 语 言, 如 Object-Pascal Object-C 等 其 中 前 期 最 成 功 并 得 到 广 泛 应 用 的 是 C++ C++ 在 OO 概 念 的 广 泛 接 受 和 应 用 方 面 功 不 可 没 ( 具 体 理 由 见 后 面 讨 论 ) 原 因 : 在 面 向 对 象 和 高 效 程 序 之 间 取 得 较 好 的 平 衡 OO 概 念 与 常 规 语 言 的 合 理 集 成 ( 在 当 时 ), 支 持 数 据 抽 象 和 面 向 对 象 的 系 统 设 计 和 程 序 设 计, 支 持 多 泛 型 程 序 设 计 的 结 合, 使 与 数 据 抽 象 和 OO 有 关 的 许 多 新 概 念 和 新 技 术 逐 渐 被 实 际 软 件 工 作 者 接 受 随 后 是 OO 分 析 OO 设 计 和 基 于 OO 的 软 件 开 发 等 等 后 来 的 其 他 成 功 语 言 包 括 Java, 微 软 提 出 C#, 等 等 出 现 了 一 些 基 于 对 象 的 脚 本 语 言, 如 Python,Ruby 等 现 在, 面 向 对 象 的 开 发 已 经 成 为 一 种 主 流 的 软 件 开 发 技 术 2012 年 5 月 11 面 向 对 象 的 基 本 概 念 面 向 对 象 的 基 本 概 念 : 在 面 向 对 象 语 言 里 定 义 数 据 抽 象 的 基 本 定 义 机 制 是 类, 在 一 个 类 里 可 以 定 义 数 据 成 员 和 子 程 序 成 员 ( 称 为 方 法 ) 封 装 是 数 据 抽 象 和 模 块 化 的 概 念, 与 面 向 对 象 的 概 念 并 没 有 必 然 关 系, 但 封 装 有 助 于 更 好 发 挥 面 向 对 象 机 制 的 作 用 ( 实 在 的 ) 类 被 看 作 类 型, 可 以 用 于 生 成 ( 定 义 ) 实 例, 称 为 对 象 已 有 的 类 可 以 作 为 定 义 新 类 的 基 础 ( 基 类 超 类 ) 可 通 过 继 承 方 式 定 义 新 类 ( 子 类, 派 生 类 ), 子 类 继 承 基 类 的 行 为 子 类 可 以 修 改 基 类 已 经 定 义 的 行 为, 或 者 增 加 所 需 的 新 行 为 把 子 类 看 作 是 子 类 型 ( 通 常 ), 如 果 D 是 B 的 子 类, 那 么 : 若 o 是 D 类 型 的 对 象, 那 么 o 也 看 作 是 B 类 型 的 对 象 若 变 量 x 可 以 引 用 B 类 的 对 象, 那 么 它 也 可 以 引 用 D 类 的 对 象 2012 年 5 月 12

面 向 对 象 的 基 本 概 念 继 承 有 两 方 面 作 用 1. 建 立 类 型 之 间 的 层 次 关 系 2. 重 用 基 类 的 行 为 ( 代 码 和 数 据 描 述 ) 对 于 面 向 对 象 的 行 为 而 言, 前 一 方 面 的 功 能 更 为 重 要 类 中 的 子 程 序 成 员 称 为 方 法, 方 法 需 要 通 过 具 体 的 对 象 调 用 在 运 行 中 调 用 方 法 时, 实 际 调 用 的 方 法 由 作 为 调 用 出 发 点 的 那 个 对 象 的 类 型 确 定 的 ( 动 态 约 束 ) 动 态 约 束 是 实 现 面 向 对 象 行 为 的 关 键 它 为 面 向 对 象 的 机 制 提 供 了 模 块 机 制 所 不 具 有 的 弹 性, 使 新 的 功 能 扩 充 可 以 比 较 自 然 地 结 合 到 已 有 的 操 作 过 程 里 理 解 动 态 约 束 是 理 解 面 向 对 象 的 关 键, 动 态 约 束 的 高 效 实 现 也 是 面 向 对 象 语 言 的 实 现 的 关 键 2012 年 5 月 13 面 向 对 象 的 语 言 虽 然 基 本 框 架 类 似, 不 同 面 向 对 象 语 言 之 间 也 存 在 很 大 差 异 : 基 本 问 题 : 采 用 什 么 样 的 对 象 模 型 采 用 单 根 的 类 层 次 结 构, 还 是 任 意 的 类 层 次 结 构? 提 供 那 些 继 承 方 式? 例 如 C++ 里 提 供 了 三 种 继 承 方 式 允 许 多 重 继 承? 还 是 只 允 许 单 继 承? 是 否 提 供 丰 富 完 善 的 访 问 控 制 机 制? 采 用 基 于 继 承 的 模 型, 还 是 基 于 指 派 的 模 型 基 于 类 的 模 型, 还 是 基 于 对 象 或 原 型 的 模 型 ( 如 JavaScript) 对 象 本 身 的 独 立 性 ( 是 否 允 许 不 属 于 任 何 一 个 类 的 对 象 ) 类 本 身 是 不 是 对 象? 2012 年 5 月 14

面 向 对 象 的 语 言 其 他 情 况 : 是 不 是 追 求 纯 粹 的 面 向 对 象 语 言? Smalltalk 尽 可 能 追 求 面 向 对 象 理 想, 完 全 是 重 新 设 计 的 新 语 言 Java 是 接 近 理 想 的 语 言, 但 希 望 在 形 式 上 尽 可 能 靠 近 常 规 语 言 C++ 设 法 在 支 持 系 统 程 序 设 计 的 过 程 性 语 言 C 上 扩 充 支 持 面 向 对 象 的 机 制, 是 一 种 多 范 型 语 言, 支 持 多 种 程 序 设 计 方 式 另 外 的 一 些 语 言 ( 如 Ada) 采 用 可 能 很 不 同 的 方 式 支 持 面 向 对 象 的 程 序 设 计, 这 里 不 准 备 详 细 介 绍 采 用 值 模 型 还 是 引 用 模 型 从 本 质 上 说, 只 有 采 用 引 用 模 型 才 能 支 持 方 法 的 动 态 约 束, 因 此 大 多 数 面 向 对 象 语 言 采 用 引 用 模 型 C++ 采 用 值 模 型, 可 以 创 建 静 态 对 象 或 栈 对 象, 但 只 有 通 过 对 象 引 用 或 指 向 对 象 的 指 针 才 能 实 现 面 向 对 象 的 动 态 约 束 行 为 Java 只 能 把 OO 功 能 应 用 于 用 户 定 义 类 型, 基 本 类 型 采 用 值 模 型 2012 年 5 月 15 面 向 对 象 的 语 言 是 否 允 许 静 态 对 象 或 者 堆 栈 对 象 ( 自 动 对 象 )? 多 数 面 向 对 象 语 言 只 支 持 堆 对 象 ( 通 过 动 态 存 储 分 配 创 建 的 对 象 ) C++ 支 持 静 态 对 象 和 自 动 对 象, 这 种 设 计 是 希 望 尽 可 能 借 助 于 作 用 域 规 则 来 管 理 对 象, 避 免 依 赖 自 动 存 储 管 理 系 统 (GC) 为 在 这 种 环 境 下 编 程, 人 们 开 发 了 许 多 利 用 自 动 对 象 的 对 象 管 理 技 术, 如 句 柄 对 象, 对 象 的 创 建 即 初 始 化 技 术 等 是 否 依 赖 自 动 废 料 收 集 (GC) 由 于 OO 程 序 常 ( 显 式 或 隐 式 地 ) 创 建 和 丢 弃 对 象, 对 象 之 间 常 存 在 复 杂 的 相 互 引 用 关 系, 由 人 来 完 成 对 象 的 管 理 和 回 收 很 困 难 大 多 数 OO 语 言 都 依 赖 于 自 动 存 储 回 收 系 统 GC 的 引 入 将 带 来 显 著 的 性 能 损 失, 还 会 造 成 程 序 行 为 更 多 的 不 可 预 见 性 (GC 发 生 的 时 刻 无 法 预 见, 其 持 续 时 间 长 短 也 无 法 预 计 ) Java 等 许 多 语 言 都 需 要 内 置 的 自 动 废 料 收 集 系 统 C++ 是 例 外, 其 设 计 目 标 之 一 是 尽 可 能 避 免 对 自 动 存 储 回 收 的 依 赖, 以 支 持 系 统 程 序 设 计, 提 高 效 率, 减 少 运 行 时 间 上 的 不 确 定 性 2012 年 5 月 16

面 向 对 象 的 语 言 是 否 所 有 方 法 都 采 用 动 态 约 束? 动 态 约 束 很 重 要, 但 调 用 时 会 带 来 一 些 额 外 的 开 销, 如 果 需 要 调 用 的 方 法 能 够 静 态 确 定, 采 用 静 态 约 束 有 速 度 优 势 大 部 分 语 言 里 的 所 有 方 法 都 采 用 动 态 约 束 C++ 和 Ada 提 供 静 态 约 束 ( 默 认 ) 和 动 态 约 束 两 种 方 式 一 些 脚 本 语 言 也 支 持 面 向 对 象 的 概 念 例 如, Ruby 是 一 个 纯 面 向 对 象 的 脚 本 语 言, 其 中 的 一 切 都 是 对 象, 全 局 环 境 看 作 一 个 匿 名 的 大 对 象, 全 局 环 境 里 的 函 数 看 作 这 个 对 象 的 成 员 函 数 它 还 有 另 外 一 些 独 特 性 质 JavaScript 支 持 一 种 基 于 对 象 和 原 型 的 面 向 对 象 模 型 其 中 没 有 类 的 概 念, 只 有 对 象 对 象 的 行 为 继 承 通 过 原 型 获 得 2012 年 5 月 17 面 向 对 象 的 语 言 人 们 还 提 出 了 许 多 与 面 向 对 象 机 制 有 关 的 新 想 法 和 模 型 许 多 新 近 的 脚 本 语 言 提 供 了 独 特 的 面 向 对 象 机 制 : 例 如 基 于 对 象 原 型 ( 而 不 是 类 ) 的 OO 模 型 在 基 于 类 的 模 型 中 允 许 基 于 对 象 的 行 为 覆 盖 ( 可 修 改 个 别 对 象 的 行 为 ) 等 等 总 而 言 之, 虽 然 今 天 面 向 对 象 的 模 型 和 语 言 已 成 为 主 流 程 序 设 计 方 法 和 主 流 程 序 语 言, 但 是 这 类 语 言 还 远 未 成 熟, 还 正 在 发 展 和 研 究 中 许 多 语 言 的 OO 机 制 非 常 复 杂, 实 际 还 不 断 提 出 一 些 新 要 求, 使 一 些 OO 语 言 在 发 展 中 变 得 越 来 越 复 杂 如 何 提 供 一 集 足 够 强 大, 而 且 又 简 洁 清 晰 的 机 制 支 持 OO 的 概 念 和 程 序 设 计, 还 是 这 个 领 域 中 需 要 继 续 研 究 的 问 题 OO 语 言 有 关 的 理 论 研 究 还 处 在 起 步 阶 段, 也 是 本 领 域 不 成 熟 的 标 志 2012 年 5 月 18

OO 语 言 需 要 提 供 的 新 机 制 定 义 类 的 语 言 机 制 ( 语 言 提 供 特 殊 的 描 述 结 构 ) 描 述 或 定 义 对 象 的 机 制 继 承 机 制, 描 述 类 之 间 的 继 承 关 系 可 能 定 义 继 承 关 系 的 性 质 ( 如 C++ 里 的 类 继 承 有 public protected 和 private 三 种 方 式 ) 与 对 象 交 互 的 机 制 ( 方 法 调 用, 消 息 传 递 ) 初 始 化 新 对 象 的 机 制 ( 最 好 能 自 动 进 行, 避 免 未 初 始 化 就 使 用 的 错 误 ) 类 类 型 对 象 的 动 态 转 换 机 制 ( 转 换 对 一 个 具 体 对 象 的 观 点 ) 控 制 类 成 员 的 访 问 权 限 的 机 制 对 象 销 毁 前 的 临 终 处 理 机 制 ( 最 好 能 自 动 进 行 ) 对 象 的 存 储 管 理 机 制 可 能 还 有 其 他 机 制 : 运 行 中 判 断 对 象 的 类 属 关 系 的 机 制 自 反 等 等 2012 年 5 月 19 OO 程 序 先 看 一 点 OO 程 序, 复 习 一 下 基 本 OO 程 序 的 特 征 这 里 看 一 段 定 义 了 几 个 类 的 C++ 代 码 定 义 list_node 类, 用 于 实 现 带 头 结 点 的 双 向 循 环 链 接 表 每 个 结 点 里 有 一 个 域 指 向 表 头 结 点 2012 年 5 月 20

OO 程 序 2012 年 5 月 21 OO 程 序 定 义 list 类 注 意 :header 是 个 list_node 定 义 的 是 有 头 结 点 的 循 环 链 表 2012 年 5 月 22

OO 程 序 通 过 继 承 定 义 queue 类 ( 只 是 作 为 示 例 ) 2012 年 5 月 23 OO 程 序 通 用 的 表 结 点 类 还 可 以 定 义 通 用 的 容 器 类 : 基 本 容 器 类 没 有 具 体 数 据 域, 不 保 存 具 体 类 型 的 元 素, 只 实 现 容 器 操 作, 如 : 一 些 基 本 判 断 谓 词, 插 入 删 除 等 等 通 过 继 承 实 现 存 储 具 体 类 型 的 元 素 的 具 体 容 器 派 生 的 int 表 结 点 类 使 用 这 种 int 表 的 问 题 : 如 果 需 要 访 问 结 点 的 数 据 内 容, 必 须 对 取 出 的 结 点 做 强 制 2012 年 5 月 24

面 向 对 象 概 念 的 实 现 实 现 面 向 对 象 的 语 言, 需 要 考 虑 它 的 几 个 标 志 性 特 征 的 实 现 封 装 是 一 种 静 态 机 制, 如 C++/Java 一 类 语 言 的 各 种 访 问 控 制 机 制 也 是 静 态 的, 都 可 以 通 过 在 符 号 表 里 记 录 信 息, 在 编 译 中 检 查 和 处 理 方 法 的 实 现 与 以 模 块 为 类 型 时 局 部 子 程 序 的 实 现 一 样 由 于 每 个 方 法 调 用 有 一 个 调 用 对 象, 因 此 方 法 需 要 一 个 隐 含 指 针, 被 调 用 时 指 向 调 用 对 象, 所 有 对 该 对 象 的 数 据 成 员 的 访 问 都 通 过 这 个 指 针 和 静 态 确 定 的 偏 移 量 进 行 许 多 语 言 以 这 一 指 针 作 为 一 个 伪 变 量, 称 为 this 或 者 self, 通 过 这 种 指 针 访 问 调 用 对 象, 方 式 上 与 通 过 指 针 访 问 普 通 结 构 一 样 实 现 面 向 对 象 语 言 的 关 键 是 两 个 问 题 : 继 承 的 实 现, 使 派 生 类 型 的 对 象 能 当 作 基 类 的 对 象 使 用 动 态 约 束 的 实 现, 能 够 从 ( 作 为 变 量 的 值 或 者 被 变 量 引 用 的 ) 对 象 出 发, 找 到 这 个 对 象 所 属 的 类 里 定 义 的 方 法 下 面 讨 论 实 现 的 一 些 具 体 问 题 2012 年 5 月 25 封 装 封 装 是 一 种 静 态 机 制, 仅 仅 在 程 序 加 工 阶 段 起 作 用, 有 关 情 况 与 模 块 机 制 类 似, 在 加 工 后 的 程 序 里 ( 可 执 行 程 序 里 ) 完 全 没 有 关 于 封 装 的 信 息 不 同 语 言 里 对 类 的 访 问 控 制 可 能 不 同 : 作 为 开 模 块 ( 允 许 以 特 定 方 式 任 意 访 问 类 成 员 ) 作 为 闭 模 块 ( 凡 是 没 有 明 确 声 明 可 访 问 的 都 不 可 访 问 ) 对 基 本 封 装 机 制 的 扩 充 是 引 进 进 一 步 的 控 制 C++ 引 进 成 员 的 public protected 和 private 属 性, 提 供 细 致 的 访 问 控 制 C++ 还 允 许 定 义 派 生 类 的 不 同 继 承 方 式, 控 制 对 基 类 成 员 的 访 问 : public 继 承 protected 继 承, 使 基 类 的 public 成 员 变 成 派 生 类 的 protected 成 员 private 继 承, 使 基 类 的 所 有 成 员 变 成 派 生 类 的 private 成 员 一 些 新 语 言 借 鉴 了 C++ 的 这 方 面 思 想, 可 能 结 合 另 外 一 些 想 法 2012 年 5 月 26

静 态 域 和 静 态 方 法 许 多 面 向 对 象 语 言 的 类 里 可 以 定 义 静 态 域 和 静 态 方 法 C++/Java 允 许 类 里 定 义 静 态 数 据 域 Smalltalk 把 普 通 的 对 象 域 称 为 实 例 变 量, 表 示 在 这 个 类 的 每 个 实 例 里 都 有 这 些 成 分 的 一 份 拷 贝 ; 把 静 态 数 据 域 称 为 类 变 量 类 的 静 态 数 据 域 并 不 出 现 在 实 例 对 象 里, 它 们 是 类 封 装 的 静 态 数 据 成 分, 提 出 具 有 静 态 生 存 期, 在 类 的 作 用 域 里 可 直 接 访 问 类 外 能 否 访 问 由 语 言 确 定 ( 提 出 有 与 其 他 成 员 一 样 的 访 问 控 制 ) 静 态 方 法 和 静 态 域 的 一 些 情 况 : 类 的 静 态 数 据 成 员 可 以 在 静 态 区 实 现, 在 程 序 运 行 之 前 静 态 分 配, 在 程 序 的 整 个 执 行 期 间 保 持 其 存 储 类 的 静 态 方 法 可 访 问 静 态 数 据 成 员, 其 他 方 法 也 可 以 访 问 静 态 数 据 成 员 可 以 把 静 态 数 据 成 员 看 作 本 类 的 所 有 对 象 共 享 的 信 息 类 对 象 可 以 通 过 静 态 数 据 成 员 交 换 或 者 共 享 信 息 2012 年 5 月 27 静 态 域 和 静 态 方 法 静 态 成 员 是 静 态 创 建 的, 其 初 始 化 在 程 序 开 始 执 行 前 完 成 ( 或 者 在 语 言 定 义 的 适 当 时 刻 完 成 ), 只 做 一 次 静 态 成 员 的 初 始 化 中 不 能 调 用 类 的 普 通 方 法 ( 因 为 没 有 对 象 ) 静 态 方 法 相 当 于 普 通 子 程 序, 只 是 具 有 类 封 装 ( 类 作 用 域 ) 特 点 : 没 有 调 用 对 象 不 能 引 用 this/self, 不 能 引 用 类 定 义 的 普 通 数 据 成 员 ( 如 Smalltalk 里 不 能 引 用 实 例 变 量 ), 只 能 引 用 本 类 的 静 态 数 据 成 员 通 常 采 用 某 种 基 于 定 义 类 的 语 法 形 式 调 用 仅 有 静 态 数 据 成 员 和 静 态 方 法 的 类, 相 当 于 一 个 简 单 模 块 提 供 模 块 的 内 部 状 态, 可 以 通 过 所 提 供 的 方 法 修 改 状 态 不 能 生 成 有 用 的 实 例 ( 生 成 的 是 空 实 例, 没 有 局 部 的 实 例 状 态 ) 静 态 数 据 成 员 的 静 态 方 法 的 封 装, 可 能 定 义 内 部 数 据 和 操 作 2012 年 5 月 28

对 象 和 继 承 : 数 据 布 局 继 承 关 系 的 数 据 部 分 通 过 对 象 的 适 当 存 储 布 局 实 现 对 象 的 实 际 表 现 就 是 数 据 成 员 的 存 储 假 定 B 是 一 个 类, 有 自 己 的 数 据 成 员 B 类 的 对 象 B 类 的 数 据 成 员 D 是 B 的 派 生 类, 增 加 了 数 据 成 员 D 类 对 象 的 前 部 仍 是 B 类 的 所 有 成 员, 扩 充 的 成 员 排 在 后 面 在 D 类 对 象 里, 所 有 B 类 成 员 相 对 于 对 象 开 始 位 置 的 偏 移 量 与 它 们 在 一 个 B 类 对 象 里 的 偏 移 量 相 同 这 样,D 类 对 象 就 可 以 作 为 B 类 对 象 使 用,B 类 里 的 方 法 能 正 确 操 作, 它 们 只 看 属 于 B 对 象 的 那 部 分 D 类 里 的 方 法 既 可 以 使 用 对 象 中 的 B 类 数 据 成 员, 也 可 以 使 用 对 象 里 的 D 类 数 据 成 员 用 D 类 对 象 给 B 类 对 象 赋 值 ( 值 copy, 或 者 值 语 义 时 ) 会 产 生 切 割 现 象,D 类 数 据 成 员 不 能 拷 贝 D 类 的 对 象 B 类 的 数 据 成 员 D 类 新 增 的 数 据 成 员 2012 年 5 月 29 初 始 化 和 终 结 处 理 对 象 可 能 具 有 任 意 复 杂 的 内 部 结 构 要 求 创 建 对 象 的 程 序 段 做 对 象 初 始 化, 需 反 复 描 述, 很 麻 烦, 易 弄 错 对 象 可 能 要 求 特 殊 的 初 始 化 方 式 和 顺 序, 对 象 的 使 用 者 难 以 贯 彻 始 终 继 承 使 对 象 的 初 始 化 更 复 杂 化, 因 为 需 要 正 确 初 始 化 继 承 来 的 数 据 成 员 为 更 容 易 处 理 对 象 初 始 化 的 问 题,OO 语 言 通 常 都 提 供 了 专 门 的 机 制, 在 对 象 创 建 时 自 动 调 用 初 始 化 操 作 保 证 新 创 建 对 象 具 有 合 法 的 状 态 自 动 调 用 非 常 有 意 义, 可 以 避 免 未 正 确 初 始 化 造 成 的 程 序 错 误 现 在 常 把 对 象 初 始 化 看 作 调 用 一 个 称 为 构 造 函 数 (constructor) 的 初 始 化 子 程 序, 它 ( 们 ) 在 对 象 的 存 储 块 里 构 造 出 所 需 要 的 对 象 语 言 通 常 支 持 参 数 化 的 初 始 化 操 作, 以 满 足 不 同 对 象 的 需 要 对 象 创 建 可 能 有 多 种 需 要, 为 此 C++/Java 等 都 支 持 一 个 类 有 多 个 不 同 的 构 造 函 数 2012 年 5 月 30

初 始 化 和 终 结 处 理 如 果 变 量 采 用 引 用 语 义, 所 有 ( 值 ) 对 象 都 需 要 显 式 创 建, 有 明 确 的 创 建 动 作 这 样 很 容 易 保 证 在 存 储 分 配 之 后 调 用 构 造 函 数 如 果 变 量 是 值, 为 保 证 初 始 化, 语 言 需 要 对 变 量 创 建 提 供 特 殊 语 义, 要 求 变 量 创 建 包 含 隐 式 的 构 造 函 数 调 用 对 象 初 始 化 必 须 按 一 定 的 顺 序 进 行 对 象 内 部 的 基 类 部 分 必 须 在 派 生 类 部 分 之 前 完 成 初 始 化, 因 为 派 生 类 新 增 的 数 据 成 员 完 全 可 能 依 赖 于 基 类 成 员 的 值 数 据 成 员 本 身 也 可 能 是 某 个 类 的 对 象, 在 执 行 整 体 对 象 的 构 造 函 数 的 过 程 中, 就 需 要 执 行 这 些 对 象 成 员 的 构 造 函 数 这 种 构 造 规 则 是 递 归 的, 语 言 必 须 严 格 定 义 对 象 的 构 造 顺 序 如 果 变 量 采 用 值 语 义 ( 例 如 C++), 在 进 入 一 个 作 用 域 的 过 程 中, 就 可 能 出 现 许 多 构 造 函 数 调 用 进 入 作 用 域 可 能 是 代 价 很 大 的 动 作 2012 年 5 月 31 初 始 化 和 终 结 处 理 在 对 象 销 毁 之 前, 可 能 需 要 做 一 些 最 后 动 作 ( 终 结 处 理 ), 例 如 释 放 对 象 所 占 用 的 各 种 资 源, 维 护 有 关 状 态 等 忘 记 终 结 处 理, 就 可 能 导 致 资 源 流 失, 或 者 状 态 破 坏 有 些 OO 语 言 提 供 终 结 动 作 定 义 机 制, 销 毁 对 象 前 自 动 执 行 所 定 义 动 作 C++ 采 用 值 语 义, 终 结 动 作 以 类 的 析 构 函 数 的 形 式 定 义 : 类 变 量 是 堆 栈 上 的 对 象, 在 其 作 用 域 退 出 时, 自 动 调 用 它 们 的 终 结 动 作 堆 对 象 需 要 显 式 释 放, 释 放 之 前 恰 好 应 该 执 行 终 结 动 作, 易 于 处 理 采 用 引 用 语 义 的 语 言 ( 如 Java), 通 常 并 不 提 供 销 毁 对 象 的 显 式 操 作 ( 以 防 悬 空 引 用 ), 对 象 销 毁 由 GC 自 动 进 行 有 了 GC, 对 终 结 动 作 的 需 求 大 大 减 少, 终 结 动 作 由 GC 自 动 进 行 执 行 终 结 动 作 的 时 间 不 可 预 计, 出 现 了 ( 时 间 和 顺 序 的 ) 不 确 定 性 对 象 关 联 和 GC 顺 序 的 不 确 定 性 使 终 结 动 作 很 难 描 述 2012 年 5 月 32

静 态 和 动 态 约 束 的 方 法 OO 语 言 里 的 方 法 调 用 通 常 采 用 x.m(...) 的 形 式, 其 中 x 是 一 个 指 向 或 者 引 用 对 象 的 变 量 m 是 x 的 定 义 类 型 ( 类, 假 定 为 B) 的 一 个 方 法 问 题 :x.m(...) 所 调 用 的 方 法 何 时 / 根 据 什 么 确 定? 两 种 可 能 性 : 根 据 变 量 x 的 类 型 ( 在 程 序 里 静 态 定 义 ) 确 定 ( 静 态 约 束 ) 根 据 方 法 调 用 时 ( 被 x 引 用 / 指 向 ) 的 当 前 对 象 的 类 型 确 定 ( 动 态 约 束 ) 由 于 x 可 能 引 用 ( 指 向 )B 类 或 其 任 何 子 类 的 对 象, 因 此 同 为 这 个 方 法 调 用, 不 同 的 执 行 中 实 际 调 用 的 完 全 可 能 是 不 同 的 方 法 所 有 OO 语 言 都 支 持 动 态 方 法 约 束 ( 否 则 就 不 是 OO 语 言 ), 多 数 以 它 作 为 默 认 方 式 少 数 语 言 同 时 也 支 持 静 态 约 束 的 方 法, 如 C++ Ada 等 C++ 把 动 态 约 束 的 方 法 称 为 虚 方 法 (virtual 方 法 ), 而 且 以 静 态 约 束 作 为 默 认 方 式 这 种 设 计 与 它 的 C 基 础 有 关 2012 年 5 月 33 静 态 约 束 的 实 现 调 用 静 态 约 束 的 方 法, 实 现 方 式 就 像 是 调 用 普 通 子 程 序 ( 过 程 / 函 数 ), 唯 一 不 同 之 处 就 是 需 要 传 入 一 个 指 向 调 用 对 象 的 指 针 在 符 号 表 里, 每 个 类 的 记 录 项 都 包 含 了 一 个 基 类 索 引, 依 靠 这 个 索 引 形 成 的 基 类 链 就 可 以 静 态 ( 编 译 时 ) 完 成 静 态 约 束 的 方 法 的 查 找 : 1. 首 先 在 变 量 所 属 的 类 ( 静 态 已 知 ) 里 查 找 ( 查 找 符 号 表 ) 如 果 在 这 里 找 到 了 所 需 要 的 方 法, 就 生 成 对 它 的 调 用 ; 如 果 不 存 在 就 反 复 做 下 一 步 2. 转 到 当 前 类 的 基 类 里 去 查 找 相 应 方 法, 如 果 找 到 就 生 成 对 它 的 调 用 ; 如 果 找 不 到 就 继 续 沿 着 基 类 链 上 溯 查 找 3. 如 果 已 无 上 层 基 类, 查 找 失 败 报 告 调 用 了 无 定 义 的 方 法 错 误 所 有 对 静 态 约 束 的 方 法 的 调 用 都 可 以 静 态 ( 编 译 时, 一 次 ) 处 理 运 行 时 的 动 作 与 一 般 子 程 序 调 用 完 全 一 样, 没 有 任 何 额 外 运 行 开 销 如 果 语 言 允 许 静 态 约 束 的 方 法, 采 用 静 态 约 束 可 以 提 高 效 率 静 态 约 束 的 方 法 还 可 以 做 inline 处 理 2012 年 5 月 34

方 法 的 动 态 约 束 class B {...... T0 tem(...) {... sp(...)... } virtual T1 sp(...) {...... } } void fun(b &x) {... x.tem(...)...} class D : public B { T1 sp(...) {...... } } B b; D d; fun(b); fun(d); B 类 里 定 义 了 一 个 一 般 性 操 作 tem, 对 所 有 B 类 对 象 都 有 价 值 tem 中 调 用 了 一 个 特 殊 操 作 sp, 该 操 作 可 能 因 子 类 不 同 而 不 同 子 类 D 覆 盖 操 作 sp 后, 仍 能 正 常 地 调 用 操 作 tem, 而 且 其 中 对 sp 的 调 用 能 调 用 到 D 类 里 新 的 操 作 定 义 这 是 OO 程 序 设 计 里 最 重 要 的 东 西 : 这 一 特 征 使 新 类 给 出 的 行 为 扩 充 ( 或 修 改 ) 可 以 自 然 地 融 合 到 已 有 功 能 里, 包 括 放 入 已 有 的 操 作 框 架 里 ( 这 个 例 子 就 是 ) 2012 年 5 月 35 动 态 约 束 的 实 现 : 一 般 模 型 对 最 一 般 的 对 象 模 型, 运 行 中 调 用 动 态 约 束 的 方 法 时 要 做 一 次 与 编 译 时 处 理 静 态 约 束 方 法 一 样 的 查 找, 这 种 查 找 可 能 非 常 耗 时 为 完 成 这 种 方 法 查 找 : 每 个 类 需 要 有 一 个 运 行 时 表 示 ( 把 类 也 作 为 程 序 对 象 ), 类 表 示 中 需 要 有 一 个 成 分 是 基 类 索 引, 还 有 一 个 成 分 是 方 法 表 每 个 对 象 里 必 须 保 存 所 属 类 的 信 息 ( 一 个 类 指 针, 指 向 其 类 ) 每 个 动 态 方 法 调 用 都 启 动 一 次 方 法 查 找 如 果 找 到 就 调 用, 找 不 到 就 发 出 一 个 message is not understood (Smalltalk) 动 态 错 误 这 种 方 式 普 遍 有 效, 可 以 处 理 具 有 任 何 动 态 性 质 的 对 象 模 型, 如 动 态 类 层 次 结 构 构 造 和 动 态 方 法 更 新 ( 修 改 添 加 和 删 除 ) 动 态 类 属 关 系 等 查 找 的 时 间 开 销 依 赖 于 继 承 链 的 长 度 和 继 承 链 上 各 个 类 中 方 法 的 个 数 这 种 方 法 的 缺 点 是 效 率 太 低 如 果 所 采 用 的 对 象 模 型 在 动 态 特 性 方 面 有 所 限 制, 就 可 能 开 发 出 效 率 更 高 的 方 法 2012 年 5 月 36

动 态 约 束 的 实 现 : 受 限 模 型 早 期 OO 语 言 ( 包 括 Smalltalk) 都 采 用 功 能 强 大 灵 活 的 对 象 模 型 在 提 供 了 极 大 灵 活 性 的 同 时, 也 带 来 效 率 上 的 巨 大 开 销 这 也 是 早 期 OO 语 言 及 其 概 念 难 被 实 际 软 件 工 作 者 接 受 的 最 关 键 原 因 提 高 算 法 效 率 的 最 基 本 途 径 是 限 制 要 解 决 的 问 题 ( 对 更 特 殊 一 些 的 问 题, 可 能 找 到 效 率 更 高 的 算 法 ), 并 设 计 优 化 的 实 现 模 型 对 于 OO 语 言, 就 是 要 找 到 一 个 受 限 的 对 象 模 型, 它 能 比 较 高 效 地 实 现, 同 时 又 能 满 足 绝 大 部 分 实 际 OO 程 序 开 发 的 需 要 常 规 OO 语 言 中 的 对 象 模 型 有 如 下 特 性 ( 足 以 支 持 常 见 程 序 设 计 工 作 ) : 类 层 次 结 构 是 静 态 确 定 的 每 个 类 里 的 动 态 约 束 方 法 的 个 数 和 顺 序 都 静 态 确 定 在 这 种 模 型 里 就 可 以 避 免 动 态 方 法 查 找, 使 方 法 调 用 的 执 行 效 率 接 近 普 通 的 子 程 序 调 用 的 执 行 效 率 (C++ 和 Stroustrup 的 贡 献 ) 2012 年 5 月 37 动 态 约 束 的 实 现 优 化 实 现 模 型, 其 中 绝 大 部 分 工 作 都 能 静 态 完 成 : 每 个 类 的 运 行 时 体 现 是 一 个 动 态 约 束 方 法 的 表 ( 称 为 虚 表,vtable), 这 是 一 个 指 针 表, 指 针 指 向 本 类 的 对 象 需 要 调 用 的 方 法 的 代 码 体 虚 表 的 指 针 按 方 法 在 类 里 的 顺 序 排 列, 每 个 方 法 对 应 于 一 个 顺 序 下 标 2012 年 5 月 38

动 态 约 束 的 实 现 在 每 个 对 象 开 头 ( 数 据 域 之 前 ) 增 加 一 个 指 针 vt 创 建 对 象 时, 设 置 其 vt 指 向 其 所 属 的 类 的 虚 表 ( 运 行 中 始 终 不 变 ) f 是 指 向 F 的 指 针 ( 或 引 用 ) 调 用 f->m(...) 的 实 现 比 调 用 静 态 约 束 的 方 法 多 了 中 间 的 两 条 指 令, 它 们 都 需 要 访 问 内 存 2012 年 5 月 39 动 态 约 束 的 实 现 虚 表 的 创 建 : 如 果 类 B 没 有 基 类, 就 将 其 定 义 里 的 动 态 约 束 方 法 的 代 码 体 指 针 依 次 填 入 它 的 虚 表 ( 下 标 从 0 或 者 1 开 始 算 ) 若 类 D 的 基 类 是 B, 建 立 D 的 虚 表 时 先 复 制 B 的 虚 表 如 D 覆 盖 了 B 的 某 个 ( 某 些 ) 动 态 约 束 方 法, 就 用 新 方 法 的 指 针 覆 盖 虚 表 里 对 应 的 已 有 指 针 若 D 定 义 了 新 的 动 态 约 束 方 法, 就 将 它 们 顺 次 加 入 虚 表, 放 在 后 面 如 果 f 指 向 的 对 象 是 B, 那 么 f->m(...) 也 会 调 用 正 确 的 方 法 2012 年 5 月 40

动 态 约 束 的 实 现 重 温 受 限 的 对 象 模 型 ( 对 一 般 程 序 设 计 已 经 足 够 强 大 ) : 类 层 次 结 构 是 静 态 确 定 的 每 个 类 里 的 动 态 约 束 方 法 的 个 数 和 顺 序 都 静 态 确 定 优 化 实 现 的 效 果 : 构 造 方 法 表 的 工 作 在 编 译 时 完 成 每 个 对 象 里 需 要 增 加 一 个 指 向 其 类 的 方 法 表 的 指 针 每 次 方 法 调 用 需 要 多 执 行 两 条 指 令 ( 典 型 情 况 ), 多 访 问 内 存 两 次 对 这 种 受 限 对 象 模 型, 动 态 约 束 方 法 调 用 的 额 外 开 销 不 大, 一 般 软 件 系 统 ( 包 括 系 统 软 件 的 绝 大 部 分 情 况 ) 都 可 以 接 受 Stroustrup 在 设 计 和 实 现 C++ 语 言 时 特 别 希 望 能 够 得 到 高 效 的 实 现, 最 后 选 择 了 这 种 对 象 模 型, 并 设 计 了 这 种 高 效 的 实 现 方 法 2012 年 5 月 41 动 态 约 束 的 实 现 对 数 据 抽 象 和 面 向 对 象 技 术 的 支 持, 以 及 高 效 的 实 现, 使 实 际 软 件 工 作 者 看 到 了 C++( 和 OO) 的 潜 力, 最 终 导 致 了 面 向 对 象 的 革 命 以 后 的 主 流 面 向 对 象 语 言 也 都 采 用 了 这 种 技 术 当 然, 采 用 这 种 选 择, 也 就 对 它 们 可 能 采 用 的 对 象 模 型 提 出 了 严 格 的 限 制 Pragmatics 里 本 章 最 后 的 练 习 里 还 讨 论 了 其 他 高 效 实 现 方 法, C++ 语 言 的 设 计 与 演 化 里 也 有 讨 论 ( 通 过 几 条 指 令 构 成 的 一 段 蹦 床 代 码, 将 控 制 转 到 实 际 应 该 调 用 的 方 法, 主 要 是 要 解 决 多 重 继 承 问 题 ) 虚 方 法 ( 动 态 约 束 方 法 ) 的 一 个 重 要 缺 点 是 不 能 做 inline 处 理 ( 在 线 展 开 要 求 静 态 确 定 被 调 用 的 方 法 ), 使 编 译 器 难 以 进 行 跨 过 程 的 代 码 优 化 C++ 希 望 支 持 高 效 的 系 统 程 序 设 计, 认 为 虚 方 法 带 来 的 效 率 损 失 有 时 也 是 不 能 容 忍 的, 因 此 它 同 时 支 持 静 态 方 法 约 束 注 意 : 如 果 一 个 类 里 只 有 静 态 约 束 的 方 法, 该 类 编 译 之 后 就 不 会 生 成 方 法 表, 该 类 的 对 象 也 没 有 一 个 指 针 的 额 外 存 储 开 销 2012 年 5 月 42

类 层 次 结 构 和 强 制 转 换 C++ 代 码 : 基 类 指 针 可 以 安 全 地 引 用 派 生 类 的 对 象, 这 时 的 ( 非 变 换 ) 自 动 类 型 转 换 称 为 向 上 强 制,upcasting 但 子 类 指 针 不 能 引 用 基 类 对 象 向 上 强 制 总 是 安 全 的, 不 会 出 问 题, 总 可 以 自 动 进 行 因 为 派 生 类 包 含 基 类 所 有 数 据 成 分, 因 此 可 以 支 持 基 类 所 有 操 作 后 一 个 赋 值 是 编 译 时 错 误, 派 生 类 指 针 不 能 引 用 基 类 对 象 2012 年 5 月 43 类 层 次 结 构 和 强 制 转 换 如 果 用 foo 类 的 指 针 q 传 递 一 个 对 象 可 保 证 该 对 象 一 定 是 foo 的 或 它 的 某 个 派 生 类 的 对 象 如 果 由 foo 类 指 针 q 传 递 的 实 际 上 是 一 个 bar 对 象, 我 们 有 时 需 要 把 它 作 为 bar 对 象 使 用, 例 如 想 对 它 调 用 foo 里 没 有 的 方 法 q->s(..) 是 静 态 类 型 错 误 (q 的 指 向 类 型 是 foo,foo 无 方 法 s) s = q 也 是 静 态 类 型 错 ( 不 能 保 证 q 指 向 的 是 bar, 赋 值 不 安 全 ) 能 不 能 用 s = (bar*)q? 如 果 q 指 向 的 确 实 是 一 个 bar 对 象, 当 前 情 况 下 恰 好 可 以, 因 为 (bar*) 对 指 针 是 非 变 换 转 换, 导 致 把 foo 指 针 当 做 bar 指 针 恰 好 bar 对 象 的 起 始 位 置 和 各 成 分 的 偏 移 量 与 foo 一 样 这 些 条 件 有 时 不 成 立 ( 下 面 会 看 到, 在 存 在 多 重 继 承 时 ) 这 种 转 换 不 安 全, 它 要 求 q 指 向 的 确 实 是 bar 动 态 怎 么 检 查 类 型? 2012 年 5 月 44

类 层 次 结 构 和 强 制 转 换 C++ 为 安 全 的 向 下 强 制 转 换 提 供 了 专 门 运 算 符 dynamic_cast 上 述 转 换 的 正 确 写 法 : bar *x = dynamic_cast<bar*>(q); 如 果 q 指 向 的 确 实 是 bar 类 的 对 象, 转 换 将 成 功,x 指 向 该 bar 类 对 象 如 果 q 指 向 的 不 是 bar 类 的 对 象, 转 换 失 败,x 被 赋 空 指 针 值 0 通 过 检 查 x 的 值, 可 以 判 断 转 换 是 否 成 功 实 现 dynamic_cast, 就 要 求 在 运 行 中 能 判 断 对 象 的 类 型 和 类 型 间 关 系 这 就 是 运 行 时 类 型 识 辨 (Run Time Type Identification,RTTI) 要 像 支 持 安 全 的 向 下 转 换,C++ 的 实 现 需 要 在 虚 表 里 增 加 一 个 类 描 述 符 常 放 在 虚 表 最 前 一 些 C++ 编 译 器 要 求 用 户 指 明 需 要 用 RTTI, 在 这 种 情 况 下 才 按 这 种 方 式 创 建 虚 表 ( 虚 表 的 形 式 与 没 有 类 描 述 符 时 不 同 ) dynamic_cast 检 查 类 型 关 系, 确 定 能 否 转 换, 在 能 转 换 就 完 成 转 换 2012 年 5 月 45 类 层 次 结 构 和 动 态 强 制 多 数 OO 语 言 ( 如 Java 等 ) 默 认 支 持 RTTI, 虚 表 里 总 保 存 类 描 述 符 如 何 描 述 类 型 是 编 译 器 的 具 体 实 现 问 题, 不 必 关 心 RTTI 机 制 可 保 证 类 型 安 全 的 转 换 虽 然 Java 的 类 型 转 换 采 用 C 语 言 类 型 转 换 的 描 述 形 式, 但 功 能 不 同 在 牵 涉 到 基 本 类 型 时, 可 能 需 要 做 值 的 转 换 在 牵 涉 到 类 类 型 时, 需 要 做 动 态 的 类 型 转 换 合 法 性 检 查 如 果 发 现 错 误, 就 抛 出 异 常 ClassCastException 否 则 做 非 变 换 类 型 转 换, 把 相 应 引 用 直 接 当 作 所 需 的 类 型 的 引 用 从 基 本 类 型 值 到 类 类 型 的 合 法 转 换, 还 需 要 自 动 构 造 对 象 (boxing); 从 类 对 象 到 基 本 类 型 值 的 转 换 需 要 提 取 对 象 内 的 值 (unboxing) 运 行 时 类 型 描 述 机 制 还 被 用 于 支 持 自 反 (reflection) 功 能 2012 年 5 月 46

多 重 继 承 有 时 需 要 从 多 个 基 类 出 发 进 行 继 承, 例 如 需 要 管 理 所 有 同 年 级 ( 一 二 三 四 年 级 ) 的 学 生 记 录, 要 建 立 学 生 的 表, 可 能 希 望 从 两 个 类 继 承 : class student : public person, public gp_list_node {...... } 这 样 student 类 的 对 象 将 同 时 具 有 : person 类 对 象 的 成 分, 因 此 可 以 记 录 个 人 信 息 并 处 理 这 些 信 息 gp_list_node 类 对 象 的 成 分, 因 此 可 作 为 表 结 点 链 入 表 中, 进 行 管 理 还 可 以 有 其 自 身 的 特 殊 的 数 据 成 员 和 操 作 通 过 多 重 继 承 定 义 的 类 是 它 的 各 个 基 类 的 子 类 这 种 派 生 类 的 对 象 也 是 它 的 各 个 基 类 的 对 象, 在 需 要 这 个 类 的 任 何 一 个 基 类 的 对 象, 都 可 以 用 这 个 类 的 对 象 student 类 的 对 象 是 person, 也 是 gp_list_node 2012 年 5 月 47 多 重 继 承 如 果 只 有 一 个 基 类, 我 们 把 基 类 对 象 的 数 据 成 员 按 照 原 来 的 位 置 存 放 在 派 生 类 对 象 数 据 区 域 的 最 前 面, 这 就 使 可 以 对 一 个 对 象 调 用 其 任 意 基 类 的 方 法, 因 为 数 据 成 员 的 位 置 相 同 也 可 以 对 派 生 类 对 象 调 用 其 所 属 类 里 定 义 或 覆 盖 的 方 法 如 果 语 言 允 许 多 重 继 承, 对 象 布 局 首 先 就 出 问 题 了 : 不 可 能 把 多 个 基 类 的 数 据 成 员 都 放 在 派 生 类 对 象 的 数 据 区 域 的 最 前 面 要 实 现 多 重 继 承, 首 先 必 须 设 计 一 种 数 据 布 局, 把 多 个 基 类 的 数 据 成 员 的 位 置 安 排 好 在 需 要 调 用 基 类 的 方 法 时, 必 须 能 够 找 到 位 于 当 前 对 象 里 的 相 应 的 基 类 对 象 所 在 的 位 置 具 体 例 子 : 需 要 能 从 任 何 一 个 student 类 的 对 象 产 生 出 它 的 person 观 察 点 和 gp_list_node 观 察 点 注 意 : 最 多 只 能 把 一 个 基 类 对 象 ( 的 数 据 成 分, 例 如 person) 放 在 student 对 象 的 最 前 面 2012 年 5 月 48

多 重 继 承 : 实 现 多 重 继 承 的 一 种 布 局 方 式 偏 移 量 d 可 静 态 确 定 在 调 用 基 类 方 法 和 向 上 向 下 强 制 时, 都 要 用 到 这 个 d 2012 年 5 月 49 多 重 继 承 : 实 现 student 的 虚 表 分 两 部 分 : 第 一 部 分 是 person 的 虚 方 法 ( 可 能 有 覆 盖 ) 和 student 新 增 虚 方 法, 虚 表 指 针 放 在 对 象 开 始 第 二 部 分 是 gp_list_node 的 虚 方 法 ( 可 能 有 覆 盖 ), 虚 表 指 针 放 在 偏 移 量 d 处 student 对 象 的 每 个 数 据 成 分 相 对 于 对 象 开 始 的 偏 移 量 可 静 态 确 定 虚 方 法 相 对 所 在 虚 表 的 偏 移 量 可 静 态 确 定 确 定 被 调 用 的 方 法 : 调 用 第 一 部 分 的 方 法, 确 定 方 法 指 针 的 方 式 与 单 继 承 一 样 调 用 gp_list_node 定 义 的 方 法, 取 对 象 地 址 值 加 d 得 到 gp_list_node 的 虚 表 地 址, 而 后 按 偏 移 量 找 到 相 应 的 方 法 指 针 2012 年 5 月 50

多 重 继 承 : 实 现 问 题 : 如 何 给 被 调 用 的 方 法 传 送 this 指 针? 如 果 只 有 单 继 承, 基 类 对 象 总 出 现 在 派 生 类 对 象 的 最 前 面 当 允 许 多 重 继 承 时, 基 类 对 象 可 能 出 现 在 派 生 类 对 象 里 的 任 何 位 置 派 生 类 对 象 基 类 对 象 派 生 类 对 象 基 类 对 象 基 类 的 this 指 针 也 就 是 整 个 ( 派 生 类 ) 对 象 的 this 指 针 如 果 只 有 对 象 里 基 类 对 象 的 this 指 针, 如 何 找 到 整 个 对 象 的 this? func (gp_list_node *x) {... x->md(...)... } 假 定 gp_list_node 有 方 法 md 实 际 调 用 func 时 送 的 可 能 是 一 个 student 对 象 在 调 用 md 时, 送 去 的 this 指 针 应 该 是 什 么? 2012 年 5 月 51 多 重 继 承 : 实 现 func (gp_list_node *x) {... x->md(...)... } 假 定 调 用 func 时 的 实 参 确 实 是 个 student 对 象, 那 么 : 若 student 没 有 覆 盖 md, 送 给 md 的 this 指 针 就 是 x 若 student 覆 盖 md, 送 给 md 的 this 应 指 向 包 含 x 所 指 对 象 的 那 个 student 对 象 调 用 func 时, 参 数 可 能 是 个 student 对 象 调 用 md 时, 送 的 this 指 针 应 是 什 么? x student 对 象 的 this gp_list_node 对 象 的 this professor 对 象 的 this 假 定 professor 从 person 的 子 类 employee 和 gp_list_node 派 生 gp_list_node 对 象 在 professor 里 的 位 置 可 能 与 在 student 里 不 同 func 也 可 能 用 于 professor x gp_list_node 对 象 的 this 函 数 func 里 怎 么 算 出 正 确 的 this 值? 注 意 : 这 一 计 算 对 每 个 派 生 类 可 能 不 同! 2012 年 5 月 52

多 重 继 承 : 实 现 func (gp_list_node *x) {... x->md(...)... } 定 义 派 生 类 ( 例 如 student professor) 之 前, 并 不 知 道 与 之 对 应 的 d 值 是 什 么 ( 而 且, 不 同 派 生 类 可 能 有 不 同 的 d 值 ) 同 一 派 生 类 的 不 同 方 法, 覆 盖 的 就 需 要 调 整, 未 覆 盖 的 不 调 整 由 于 动 态 约 束, 编 译 时 ( 静 态 ) 不 知 道 该 不 该 调 整 this 值 结 论 : 如 果 没 有 其 他 信 息, 编 译 不 知 道 怎 么 计 算 送 给 md 的 this 值 细 节 情 况 : 调 整 或 者 不 调 整, 是 由 具 体 的 方 法 确 定 的 即 使 要 调 整, 对 于 不 同 的 类 也 可 能 需 要 不 同 的 调 整 值 解 决 办 法 是 在 派 生 类 ( 的 虚 表 ) 里 为 计 算 this 值 提 供 信 息 一 种 方 法 : 在 虚 表 里 为 每 个 方 法 指 针 附 一 个 this 校 正 值 如 果 student 覆 盖 方 法 m, 其 校 正 值 为 -d, 没 覆 盖 时 调 整 值 为 0 调 用 m 时 给 当 时 的 this 加 上 这 个 校 正 值, 而 后 转 入 方 法 体 2012 年 5 月 53 多 重 继 承 : 实 现 假 定 对 象 是 my_student 假 定 调 用 gp_list_node 的 第 三 个 方 法 实 现 调 用 的 指 令 : r3 是 被 调 方 法 指 针,r1 是 送 给 方 法 的 this 值 如 果 语 言 里 存 在 多 重 继 承, 所 有 方 法 表 都 要 增 加 this 校 正 值, 每 次 方 法 调 用 都 必 须 考 虑 this 校 正 ( 回 想 前 面 例 子 ) 实 现 的 复 杂 性, 空 间 开 销 和 方 法 调 用 的 时 间 开 销 都 增 加 了 无 论 一 个 类 是 否 用 到 多 重 继 承, 都 需 要 付 出 额 外 代 价 代 价 是 全 局 性 的, 即 使 不 用 ( 不 用 多 重 继 承 ) 也 要 付 出 代 价 2012 年 5 月 54

多 重 继 承 : 歧 义 性 假 定 person 和 gp_list_node 里 都 定 义 了 debug_print 方 法 现 在 有 student* 类 型 的 变 量 s, 问 : s->debug_print() 调 用 哪 个 方 法 这 是 多 重 继 承 引 起 的 语 义 歧 义 性 问 题 不 同 语 言 采 用 了 不 同 处 理 方 法 C++ 要 求 明 确 重 新 定 义 存 在 歧 义 的 方 法 ( 否 则 编 译 报 错 ): 如 果 程 序 里 总 是 要 顺 序 地 调 用 两 个 方 法 如 有 可 能 需 要 分 别 调 用 两 个 方 法 中 的 任 何 一 个 2012 年 5 月 55 多 重 继 承 : 歧 义 性 如 同 名 方 法 是 虚 方 法, 需 要 在 多 重 继 承 的 派 生 类 里 覆 盖, 问 题 更 难 办 ( 覆 盖 哪 一 个 ) Stroustrup 提 出 了 定 义 转 接 类 作 为 过 渡 的 技 术 : 这 里 就 可 以 分 别 写 覆 盖 定 义 其 他 提 供 多 重 继 承 的 语 言 可 能 支 持 不 同 方 式 2012 年 5 月 56

多 重 继 承 : 歧 义 性 如 果 派 生 类 D 继 承 基 类 B 和 C, 而 B 和 C 都 继 承 一 个 公 共 基 类 A 在 D 类 型 的 对 象 里 到 底 有 几 个 A 对 象?( 一 个 还 是 两 个?) 书 上 的 例 ( 在 职 研 究 生 ): class professor : public person, public gp_list_node {...... } class student_prof : public student, public professor {...... } student_prof 继 承 person 和 gp_list_node 各 两 次 gp_list_node person gp_list_node 可 能 希 望 student_prof 对 象 里 : 只 有 一 个 person( 是 同 一 个 人 ) student professor 有 两 个 gp_list_node( 以 便 可 以 链 接 到 两 个 不 同 的 表 里 ) student_prof 希 望 的 继 承 形 式 2012 年 5 月 57 多 重 继 承 : 歧 义 性 两 种 不 同 需 要 和 相 应 的 继 承 概 念 对 gp_list_node 的 继 承 要 求 为 继 承 树 的 不 同 分 支 分 别 提 供 不 同 的 副 本, 这 种 方 式 称 为 复 本 式 继 承 对 person 的 继 承 要 求 所 有 分 支 只 有 一 个 副 本, 称 为 共 享 式 继 承 C++ 里 默 认 为 复 本 式 继 承 可 以 为 基 类 加 virtual 修 饰, 要 求 采 用 共 享 式 继 承 class professor : public virtual person, public gp_list_node {...... } class student : public virtual person, public gp_list_node {...... } class student_prof : public student, public professor {...... } 前 一 定 义 保 证 最 终 的 student_prof 对 象 符 合 我 们 的 需 要 其 他 支 持 多 重 继 承 的 OO 语 言 在 这 方 面 可 能 有 不 同 的 规 定 2012 年 5 月 58

多 重 继 承 : 复 本 式 复 本 式 继 承 没 有 引 进 任 何 新 问 题 类 D 通 过 两 条 不 同 路 径 继 承 两 个 基 类 A, 其 对 象 里 有 两 份 A 数 据 成 分 方 法 表 里 有 两 组 A 的 虚 方 法 项 究 竟 调 用 那 里 的 方 法, 要 根 据 取 得 D 对 象 的 哪 个 基 类 观 察 点 (B 或 C) 确 定 2012 年 5 月 59 多 重 继 承 : 复 本 式 不 能 直 接 从 D 对 象 出 发 访 问 A 的 方 法 必 须 先 转 到 B 或 C 观 点 ( 通 过 指 针 或 引 用 方 式 ), 而 后 才 能 调 用 A 的 方 法 虚 表 项 里 也 需 要 校 正 值 2012 年 5 月 60

多 重 继 承 : 共 享 式 现 在 D 对 象 里 只 有 一 个 A 对 象, 应 该 只 有 一 组 A 的 虚 方 法 如 果 没 有 覆 盖, 情 况 还 比 较 简 单 若 B 覆 盖 了 A 的 虚 方 法 f, 那 么 D 应 该 通 过 C 继 承 原 来 A 的 方 法 f, 还 是 由 B 继 承 新 定 义 的 f? 出 现 歧 义!( 两 个 类 都 覆 盖 的 情 况 类 似 ) 这 是 共 享 式 继 承 带 来 的 新 问 题 2012 年 5 月 61 多 重 继 承 : 共 享 式 C++ 禁 止 这 种 歧 义 性, 要 求 : 如 果 存 在 覆 盖, 必 须 有 一 个 定 义 位 于 其 他 相 关 类 的 公 共 派 生 类 里 上 面 情 况 不 满 足 这 一 规 定, 因 此 不 合 法 其 他 语 言 ( 如 果 有 多 重 继 承 ) 可 能 采 取 不 同 的 管 理 策 略 处 理 这 个 问 题 在 Eiffel 语 言 里 如 果 一 个 类 可 能 从 多 个 基 类 继 承 来 同 一 方 法 的 不 同 版 本, 可 以 在 这 个 类 里 明 确 说 明 要 继 承 哪 一 个 也 可 以 通 过 重 命 名 的 方 式 消 解 这 种 歧 义 性 2012 年 5 月 62

多 重 继 承 : 共 享 式 布 局 : 在 D 对 象 里 只 有 一 个 A 对 象 D 里 的 B 对 象 和 C 对 象 不 可 能 都 连 续 图 中 方 式 是 让 D 里 的 B 和 C 都 不 连 续, A 部 分 单 独 放 置 这 时 需 要 在 各 个 派 生 类 对 象 里 保 存 A 对 象 的 地 址 这 个 地 址 相 对 于 各 子 对 象 的 距 离 都 是 编 译 确 定 的 常 量 2012 年 5 月 63 多 重 继 承 : 共 享 式 数 据 成 员 访 问 : 要 访 问 A 的 成 员, 根 据 偏 移 量 计 算 后 间 接 取 成 员 要 调 用 A 里 的 第 n 个 虚 方 法 : 这 里 还 是 需 要 在 虚 表 里 保 存 this 校 正 值 存 在 解 决 问 题 的 其 他 方 式 ( 蹦 床 代 码 ) 2012 年 5 月 64

混 入 式 继 承 Java 代 码 示 例 : 向 一 个 ( 一 组 ) 类 里 逐 步 混 入 若 干 接 口 (interface) 的 虚 方 法 三 个 接 口 : 排 序 显 示 保 存 继 承 widget, 混 入 一 个 接 口 的 方 法 实 现 2012 年 5 月 65 混 入 式 继 承 混 入 另 外 两 个 接 口 的 方 法 实 现 augmented_widget 可 以 放 入 排 序 表 可 以 在 窗 口 里 显 示 可 以 保 存 到 字 典 里 2012 年 5 月 66

2012 年 5 月 67 混 入 式 继 承 混 入 式 继 承 的 布 局 和 方 法 调 用 : 成 员 布 局 可 以 简 单 地 根 据 逐 步 混 入 的 顺 序 排 列 各 个 混 入 部 分 建 立 独 立 的 方 法 表 在 每 个 方 法 表 前 面 加 一 个 this 修 正 量 项 这 一 修 正 量 由 这 个 表 里 所 有 的 方 法 共 享 因 为 这 些 方 法 都 是 一 起 定 义 的 不 能 直 接 把 混 入 的 方 法 直 接 加 在 原 来 的 方 法 表 之 后, 因 为 每 个 观 点 都 需 要 像 一 个 独 立 的 对 象, 可 以 独 立 操 作 和 使 用 2012 年 5 月 68

面 向 对 象 的 部 分 总 结 面 向 对 象 的 三 个 基 本 概 念 : 封 装 ( 数 据 抽 象 ) 继 承 ( 类 型 扩 充, 代 码 重 用 ) 动 态 方 法 约 束 ( 调 整 抽 象 的 行 为 方 式 ) 实 现 面 向 对 象 的 支 持 : 需 要 引 用 或 者 指 针 概 念 的 支 持 需 要 考 虑 自 动 的 初 始 化 和 终 结 处 理 通 常 需 要 以 废 料 收 集 为 主 要 特 征 的 存 储 管 理 机 制 的 支 持 运 行 中 最 重 要 的 问 题 是 支 持 动 态 约 束 在 受 限 的 对 象 模 型 中, 可 以 通 过 虚 表 技 术 得 到 很 好 的 性 能 多 重 继 承 可 以 解 决 一 些 编 程 问 题, 但 也 带 来 概 念 和 实 现 方 面 的 困 难 和 代 价 混 入 方 式 可 以 在 许 多 情 况 下 替 代 多 重 继 承 2012 年 5 月 69