Java 版 (精华区)

作  家: pcy (po) on board 'java'
题  目: java教程(十)
来  源: 哈尔滨紫丁香站
日  期: Wed Jul 16 13:48:17 1997
出  处: bbs@conger.neu.edu.cn

发信人: Jin_Hu@bbs.ustc.edu.cn (快乐老虎,啦~~~), 信区: java
标  题: java教程(十)『转』
发信站: 中国科大BBS站 (Sun Apr 27 21:52:18 1997)
转信站: neubbs!sjtunews!ustcnews!ustcbbs

发信人: Only (是意外的惊喜), 信区: Java
标  题: java教程(十)
发信站: 饮水思源 (Fri Dec  6 18:43:50 1996)



JAVA程 序 设 计 语 言 讲 座 (第 12讲 )

                         第 一 部 分 Java入 门 

                     第 六 章 对 象 、 类 、 包 和 接 口 

     6.3.3 对 象 的 清 除 

     Java运 行 时 系 统 通 过 垃 圾 收 集 周 期 性 地 释 放 无 用 对 象 所 使 用
的 内 存 ,完 成 对 象 的 清 除 。 当 不 存 在 对 一 个 对 象 的 引 用 (当 前 的 代
码 段 不 属 于 对 象 的 作 用 域 或 把 对 象 的 引 用 赋 值 为 null,如 p=null )时 ,该
对 象 成 为 一 个 无 用 对 象 。 Java的 垃 圾 收 集 器 自 动 扫 描 对 象 的 动 态
内 存 区 ,对 被 引 用 的 对 象 加 标 记 ,然 后 把 没 有 引 用 的 对 象 作 为 垃 圾
收 集 起 来 并 释 放 。 

     垃 圾 收 集 器 作 为 一 个 线 程 运 行 。 当 系 统 的 内 存 用 尽 或 程 序 中
调 用 System.gc()要 求 进 行 垃 圾 收 集 时 ,垃 圾 收 集 线 程 与 系 统 同 步 运 行
。 否 则 垃 圾 收 集 器 在 系 统 空 闲 时 异 步 地 执 行 。 

     在 C中 ,通 过 free来 释 放 内 存 ,C++中 则 通 过 delete来 释 放 内 存 ,这 种
内 存 管 理 方 法 需 要 跟 踪 内 存 的 使 用 情 况 ,不 仅 复 杂 而 且 还 容 易 造 成
系 统 的 崩 溃 ,Java 采 用 自 动 垃 圾 收 集 进 行 内 存 管 理 ,使 程 序 员 不 需 要
跟 踪 每 个 生 成 的 对 象 ,避 免 了 上 述 问 题 的 产 生 ,这 是 Java的 一 大 优 点
。 

     在 6.2.7中 已 经 讲 述 ,在 对 象 作 为 垃 圾 被 收 集 前 ,Ja-va运 行 时 系 统
会 自 动 调 用 对 象 的 finalize()方 法 ,使 它 清 除 自 己 所 使 用 的 资 源 。 

                       § 6.4 父 类 、 子 类 和 继 承 

     Java中 ,所 有 的 类 都 是 通 过 直 接 或 间 接 地 继 承 java.lang.Object得 到
的 。 继 承 而 得 到 的 类 为 子 类 ,被 继 承 的 类 为 父 类 ,父 类 包 括 所 有 直
接 或 间 接 被 继 承 的 类 。 子 类 继 承 父 类 的 状 态 和 行 为 ,同 时 也 可 以 修
改 父 类 的 状 态 或 重 载 父 类 的 行 为 ,并 添 加 新 的 状 态 和 行 为 ,Java中 不
支 持 多 重 继 承 。 

     6.4.1 创 建 子 类 

     通 过 在 类 的 声 明 中 加 入 extends子 句 来 创 建 一 个 类 的 子 类 ,其 格
式 如 下 : 

    class SubClass extends SuperClass {
          ……
    }


     把 SubClass声 明 为 SuperClass的 直 接 子 类 ,如 果 Su-perClass又 是 某 个 类
的 子 类 ,则 SubClass同 时 也 是 该 类 的 (间 接 )子 类 。 子 类 可 以 继 承 所 有
父 类 的 内 容 。 

     如 果 缺 省 extends子 句 ,则 该 类 为 java.lang.Object的 子 类 。 

     子 类 可 以 继 承 父 类 中 访 问 权 限 设 定 为 public, protected, friendl y的 成
员 变 量 和 方 法 。 但 是 不 能 继 承 访 问 权 限 为 pri-vate的 成 员 变 量 和 方
法 。 有 关 访 问 权 限 的 内 容 ,请 参 见 § 6.6。 

     6.4.2 成 员 变 量 的 隐 藏 和 方 法 的 重 载 

     我 们 先 看 一 个 例 子 : 

    例6.7
    class SuperClass{
          int x;
          ……
          void setX(){
                x = 0;
          }
          ……
    }
    class SubClass extends SuperClass{
          int x;            ∥hide x in SuperClass
          ……
          void setX(){  ∥overload method setX() in SuperClass
                x = 5;
          }
          ……
    }


     该 例 中 ,SubClass是 SuperClass的 一 个 子 类 。 其 中 声 明 了 一 个 和 父
类 SuperClass同 名 的 变 量 x,并 定 义 了 与 之 相 同 的 方 法 setX, 这 时 在 子 类
SubClass中 ,父 类 的 成 员 变 量 x被 隐 藏 ,父 类 的 方 法 setX被 重 载 。 于 是 子
类 对 象 所 使 用 的 变 量 x为 子 类 中 定 义 的 x,子 类 对 象 调 用 的 方 法
setX()为 子 类 中 所 实 现 的 方 法 。 

     注 意 ,重 载 的 方 法 和 父 类 中 被 重 载 的 方 法 要 具 有 相 同 的 名 字
,相 同 的 参 数 表 和 相 同 的 返 回 类 型 。 

     子 类 通 过 成 员 变 量 的 隐 藏 和 方 法 的 重 载 可 以 把 父 类 的 状 态 和
行 为 改 变 为 自 身 的 状 态 和 行 为 。 

     6.4.3 super

     子 类 在 隐 藏 了 父 类 的 成 员 变 量 或 重 载 了 父 类 的 方 法 后 ,常 常 还
要 用 到 父 类 的 成 员 变 量 ,或 在 重 载 的 方 法 中 使 用 父 类 中 被 重 载 的 方
法 以 简 化 代 码 的 编 写 ,这 时 就 要 访 问 父 类 的 成 员 变 量 或 调 用 父 类 的
方 法 ,Java中 通 过 super来 实 现 对 父 类 成 员 的 访 问 。 

     Java中 ,this用 来 引 用 当 前 对 象 ,与 this 类 似 ,super用 来 引 用 当 前 对 象
的 父 类 。 

     super的 使 用 有 三 种 情 况 :

     1. 用 来 访 问 父 类 被 隐 藏 的 成 员 变 量 ,如 :

     super.variable

     2. 用 来 调 用 父 类 中 被 重 载 的 方 法 ,如 :

     super.Method ( [paramlist] );

     3. 用 来 调 用 父 类 的 构 造 函 数 ,如 :

     super( [paramlist] ); 

     我 们 通 过 下 例 来 说 明 super的 使 用 ,以 及 成 员 变 量 的 隐 藏 和 方 法
的 重 载 。 

    例6.8
    class superClass{
          int x;
          superClass(){
                x = 3;
                System.out.println("in superClass : x = "+x);
          }
          void doSomething(){
            System.out.println("in superClass.doSomething()");
          }
    }
    class subClass extends superClass{
          int x;
          subClass(){
                super();    ∥call constructor of superClass
                x = 5;
                System.out.println("in subClass   : x = "+x);
          }
          void doSomething(){
               super.doSomething();∥call method of superClass
             System.out.println("in subClass.doSomething()");
                System.out.println("super.x = "+super.x+"  sub.x = "+x);
          }
    }
    public class inheritance{
          public static void main( String args[] ){
                subClass subC = new subClass();
                subC.doSomething();
          }
    }
    运行结果为:
    C:\>java inheritance
    in superClass : x = 3
    in subClass   : x = 5
    in superClass.doSomething()
    in subClass.doSomething()
    super.x = 3  sub.x = 5


     通 常 ,在 实 现 子 类 的 构 造 方 法 时 ,先 调 用 父 类 的 构 造 方 法 。 在
实 现 子 类 的 finalize ()方 法 时 ,最 后 调 用 父 类 的 finalize()方 法 ,这 符 合 层 次
化 的 观 点 以 及 构 造 方 法 和 finalize()方 法 的 特 点 。 即 初 始 化 过 程 总 是
由 高 级 向 低 级 ,而 资 源 回 收 过 程 应 从 低 级 向 高 级 进 行 。 

     6.4.4 运 行 时 多 态 

     对 于 重 载 或 继 承 的 方 法 ,Java运 行 时 系 统 根 据 调 用 该 方 法 的 实
例 的 类 型 来 决 定 选 择 哪 个 方 法 调 用 。 对 子 类 的 一 个 实 例 ,如 果 子 类
重 载 了 父 类 的 方 法 ,则 运 行 时 系 统 调 用 子 类 的 方 法 ,如 果 子 类 继 承
了 父 类 的 方 法 (未 重 载 ),则 运 行 时 系 统 调 用 父 类 的 方 法 。 因 此 ,一 个
对 象 可 以 通 过 引 用 子 类 的 实 例 调 用 子 类 的 方 法 。 如 下 例 所 示 : 

    例6.9
    class A{
          void callme(){
           System.out.println("Inside A's callme() method");
          }
    }
    class B extends A{
          void callme(){
             System.out.println("Inside B's callme() method");
          }
    }
    public class Dispatch{
          public static void main( String args[] ){
                A a = new B();
                a.callme();
          }
    }
    运行结果为:
    C:\>java Dispatch
    Inside B's callme() method


     该 例 中 ,我 们 声 明 了 A类 型 的 变 量 a,然 后 用 new建 立 A类 型 的 子 类
B的 一 个 实 例 b,并 把 对 该 实 例 的 一 个 引 用 存 贮 到 a中 ,Java运 行 时 系 统
分 析 该 引 用 是 类 型 B的 一 个 实 例 ,因 此 调 用 子 类 B的 callme方 法 。 

     用 这 种 方 式 我 们 可 以 实 现 运 行 时 的 多 态 ,它 体 现 了 面 向 对 象 程
序 设 计 中 的 代 码 复 用 和 鲁 棒 性 。 已 经 编 译 好 的 类 库 可 以 调 用 新 定
义 的 子 类 的 方 法 而 不 必 重 新 编 译 ,而 且 还 提 供 了 一 个 简 明 的 抽 象 接
口 ,如 上 例 中 ,如 果 增 加 几 个 A的 子 类 的 定 义 ,则 用 a.callme()可 以 分 别 调
用 多 个 callme()可 以 分 别 调 用 多 个 子 类 的 不 同 的 callme()方 法 ,只 需 分 别
用 new生 成 不 同 子 类 的 实 例 即 可 。 

     6.4.5 final类 和 方 法 

     final类 不 能 被 继 承 。 由 于 安 全 性 的 原 因 或 者 是 面 向 对 象 的 设 计
上 的 考 虑 ,有 时 候 希 望 一 些 类 不 能 被 继 承 ,例 如 ,Java中 的 String类 ,它 对
编 译 器 和 解 释 器 的 正 常 运 行 有 很 重 要 的 作 用 ,不 能 对 它 轻 易 改 变
,因 此 把 它 修 饰 为 final类 ,使 它 不 能 被 继 承 , 这 就 保 证 了 String类 型 的 唯
一 性 ,同 时 ,如 果 你 认 为 一 个 类 的 定 义 已 经 很 完 美 ,不 需 要 再 生 成 它
的 子 类 ,这 时 也 应 把 它 修 饰 为 final类 ,定 义 一 个 final类 的 格 式 如 下 : 

    final class finalClassName{
          ……
    }
    同样,有些方法不能被重载,这时把它限定为final方法,其格式为:
    final returnType finalMethod ( [paramlist] ){
          ……
    }


     6.4.6 abstract类 和 方 法 

     与 final类 和 方 法 相 反 ,abstract类 必 须 被 继 承 ,abstract方 法 必 须 被 重
载 。 

     当 一 个 类 的 定 义 完 全 表 示 抽 象 的 概 念 时 ,它 不 应 该 被 实 例 化 为
一 个 对 象 。 例 如 Java中 的 Number类 就 是 一 个 抽 象 类 ,它 只 表 示 数 字 这
一 抽 象 概 念 ,只 有 当 它 作 为 整 数 类 Integer或 实 数 类 Float等 的 父 类 时 它
才 有 意 义 ,定 义 一 个 抽 象 类 的 格 式 如 下 : 

    abstract class abstractClass{
          ……
    }


     由 于 抽 象 类 不 能 被 实 例 化 ,因 此 下 面 的 语 句 会 产 生 编 译 错 误 : 

     new abstractClass(); ∥ abstract class can't be in-stantiated 

     抽 象 类 中 可 以 包 含 抽 象 方 法 ,为 所 有 子 类 定 义 一 个 统 一 的 接 口
,对 抽 象 方 法 只 需 声 明 ,而 不 需 实 现 ,其 格 式 如 下 : 

     abstract returnType abstractMethod( [paramlist] ); 

      (未 完 待 续 ) 

--
※ 来源:.饮水思源 bbs.sjtu.edu.cn.[FROM: 202.120.3.150]

※ 来源: 中国科大BBS站 [bbs.ustc.edu.cn]

--
※ 来源:·哈尔滨紫丁香站 bbs1.hit.edu.cn·[FROM: bbs@conger.neu.edu.c] 
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.135毫秒