Microsoft Word - 第3章.doc

Size: px
Start display at page:

Download "Microsoft Word - 第3章.doc"

Transcription

1 CHAPTER3 面向对象程序设计 第 3 章 Java 语言是一种面向对象的高级程序语言 应用面向对象语言求解问题的基本思路是, 首先分析问题并建立相应的对象, 然后通过这些对象以及它们之间的配合解决问题, 其中每个对象在计算机中占用一定的内存, 同时能够完成一定的功能 这种基本思想实际上是模拟现实生活求解问题的一般过程 在现实生活中, 任何一个人或任何一种物体都可以被认为是对象 例如, 人一般拥有手 脚和头脑等物质基础, 同时具有走路 开车和做出各种决策等能力 又如, 汽车拥有车轮 发动机 方向盘 座椅 车门和车窗等物质基础, 同时具有启动 行驶 变速和停车等功能 在现实生活中, 人和汽车相互配合可以解决一些实际问题, 例如驾驶汽车从北京到上海, 从美国的芝加哥到纽约等 3.1 类 域 方法和实例对象 在 Java 语言中, 对象的构造主要通过类, 类 (class) 是实例对象的模板 类的定义格式是 : [ 类修饰词列表 ] class 类名 [extends 父类名 ] [implements 接口名称列表 ] 类体 } 其中, 中括号 [ ] 表示被其括起来的内容是可选项, 即在类定义中可以不包含该选项 ; 格式第一行的内容称为类定义的头部或当前定义的类的声明 类修饰词列表可以包含 0 个或者 1 个或者多个类修饰词 如果存在多个类修饰词, 则在相邻两个类修饰词之间采用空格分隔 类修饰词用来说明类的属性, 包括 public abstract final 和 strictfp 等 类修饰词 public 表示上面定义的类可以被 Java 的所有软件包使用 如果在类修饰词列表中不含有 public 关键字, 则上面定义的类只能在当前的软件包中使用 类修饰词 abstract 表示上面定义的类是一个抽象类 类修饰词 final 表示上面定义的类不能用作父类 类修饰词 strictfp 表明在上面定义的类中各个浮点数的表示及其运算严格遵循电气电

2 64 J ava 程序设计 ( 第 2 版 ) 子工程师学会 (Institute of Electrical and Electronics Engineers,IEEE)754 算术国际标准 类名可以是任意的合法标识符 如果在类的定义中含有类修饰词 public, 则该类应当与其 所在的文件前缀同名 (Java 源文件名的后缀一定是.java ) 在同一个 Java 源文件中可以包含多个类, 但不能包含两个或两个以上的具有 public 修饰词的类 在上面类的定义格式中, 可选项 extends 父类名 指定所定义类的父类, 即所定义的类将具有其父类所定义的一些属性和功能 在上面的类定义中, 如果不含有选项 extends 父类名, 则上面定义的类的父类是 java.lang.object, 即不含有选项 extends 父类名 与包含选项 extends java.lang.object 具有相同的功能 这里的类 java.lang.object 是除了其自身以外的所有类的直接或间接父类 可选项 implements 接口名称列表 表明上面定义的类是实现这些给定接口的类, 即上面定义的类将具有这些给定接口的属性和功能 接口名称列表可以包含一个或多个接口名称 如果存在多个接口, 则在接口之间采用逗号分隔 在类体部分可以定义类的构造方法和类的两类成员要素, 即成员域 (field) 和成员方法 (method) 类的成员域简称为域, 通常用来表示和存储类所需要的数据, 其格式为 : [ 域修饰词列表 ] 类型变量名或带初始化的变量名列表 ; 其中, 域修饰词列表是可选项, 即可以不含有该选项 在上面的格式中, 类型 指定当前成员域的类型 类型 可以是基本数据类型, 例如 int; 类型 也可以是引用数据类型, 例如类名 变量名或带初始化的变量名列表可以包含一个或多个变量名, 其中每个变量名是一个合法的标识符 如果含有多个变量名, 则在相邻的变量名或带初始化的变量名之间采用逗号分隔 当在上面的格式中含有多个变量名时, 上面的格式实际上定义了多个成员域, 即每个变量名对应一个成员域 这里带初始化的变量名实际上包含赋值运算, 即等号的左侧是变量名, 等号的右侧是一个表达式, 该表达式的值将成为等号左侧变量的值, 例如 : int m_radius = 0; 上面的语句采用带初始化的变量名形式定义了成员域 m_radius, 它的值为 0 在上面成员域的定义格式中, 域修饰词列表可以包含 0 个 1 个或者多个域修饰词 如果存在多个域修饰词, 则在相邻两个域修饰词之间采用空格分隔 域修饰词通常包括 public protected private static final transient 和 volatile 域修饰词 public protected 和 private 不能同时存在, 它们表示当前定义的成员域的访问控制属性, 即当前定义的成员域的应用范围 这 3 个域修饰词的具体含义参见 3.5 节关于封装性的介绍 域修饰词 static 表明当前定义的成员域是静态 (static) 的, 域修饰词 static 的具体使用方法参见 3.6 节关于修饰词的介绍 域修饰词 final 通常要求成员域在首次赋值之后不能再修改该成员域的值 对于具有 final 和 static 属性的成员域, 通常要求采用带初始化的变量名的形式定义 ; 如果不带初始化, 则该成员域的值通常只能为默认值 对于具有 final 属性但不具有 static 属性的成员域, 除了采用带初始化的变量名的形式定义给该成员域赋初值之外, 通常还可以在构造方法中给不带初始化的成员域进行一次赋值操作 修饰词 transient 表明当前的成员域是一种暂时的成员域, 即当保存对象时可以不保存当前的成员域 修饰词 volatile 主要用在多线程程序设计中, 表明在访问当前成员域时将采用同步机制 类的成员方法简称为方法, 通常用来实现类的各种功能, 其格式为 : [ 方法修饰词列表 ] 返回类型方法名 ( 方法的参数列表 )

3 65 第 3 章面向对象程序设计 } 方法体 其中, 方法修饰词列表是可选项, 即可以不含该选项 ; 格式第一行的内容称为成员方法定义的头部或者当前定义的成员方法的声明 在上面的格式中, 返回类型指定当前成员方法返回的数据的数据类型 返回类型可以是基本数据类型, 例如 int; 返回类型也可以是引用数据类型, 例如类名 如果成员方法不返回任何数据, 则应当在返回类型处写上关键字 void, 否则将出现编译错误 方法名是一个合法的标识符, 用来标识当前的成员方法 方法的参数列表可以包含 0 个 1 个或多个参数 当在参数列表处除了空格之外不含任何字符时, 表明该参数列表不含任何参数 这里需要注意的是, 不能在参数列表处写上关键字 void, 否则将出现编译错误 在参数列表中, 每个参数的格式是 : 类型参数变量名其中, 类型可以是基本数据类型或引用数据类型, 参数变量名可以是一个合法的标识符 如果在参数列表中包含多个参数, 则在参数之间采用逗号分隔 方法体通常由一些语句组成, 主要用来实现当前成员方法的功能 方法修饰词列表可以包含 0 个 1 个或者多个方法修饰词 如果存在多个方法修饰词, 则在相邻两个方法修饰词之间采用空格分隔 方法修饰词用来说明成员方法的属性, 方法修饰词通常包括 public protected private abstract static final synchronized 和 strictfp 方法修饰词 public protected 和 private 不能同时存在, 它们表示当前定义的成员方法的访问控制属性, 即当前成员方法的封装性, 具体参见 3.5 节关于封装性的介绍 方法修饰词 abstract 表明当前成员方法是抽象成员方法, 抽象成员方法不能含有方法体, 而且一般在抽象类或者接口中定义, 具体介绍参见 3.6 节 方法修饰词 static 表明当前定义的成员方法是静态的, 方法修饰词 static 的具体使用方法参见 3.6 节关于修饰词的介绍 如果当前成员方法含有方法修饰词 final, 则在当前成员方法所在的类的子类中不能出现与当前成员方法相同的声明, 具体介绍参见 3.6 节 方法修饰词 synchronized 表明当前成员方法是一种同步成员方法 方法修饰词 strictfp 表明在当前成员方法中各个浮点数的表示及其运算严格遵循 IEEE 754 算术国际标准 下面给出一些成员方法定义的头部示例 : public int mb_method( ) public static void main(string args[ ]) 其中, 关键字 public 和 static 是方法修饰词,int 和 void 是返回类型, 第一个成员方法不含任何参数, 第二个成员方法含有一个参数,args 是第二个成员方法的参数变量,args 的类型是字符串 (String) 数组类型 类的构造方法主要用来创建类的实例对象, 通常同时完成新创建的实例对象的初始化工作, 例如给实例对象的成员域赋初值 定义构造方法的格式为 : [ 构造方法修饰词列表 ] 类名 ( 方法的参数列表 ) 方法体 }

4 66 J ava 程序设计 ( 第 2 版 ) 其中, 构造方法修饰词列表是可选项, 即可以不含该选项 ; 格式第一行的内容称为构造方法定义的头部或当前定义的构造方法的声明 构造方法修饰词列表可以包含 0 个 1 个或者多个构造方法修饰词 如果存在多个构造方法修饰词, 则在相邻两个构造方法修饰词之间采用空格分隔 构造方法修饰词用来说明构造方法的属性, 构造方法修饰词通常包括 public protected 和 private 这 3 个修饰词表示当前定义的构造方法的访问控制属性, 即封装性, 它们不能同时存在, 具体参见 3.5 节关于封装性的介绍 在构造方法定义格式处的类名必须与该构造方法所在的类的类名完全相同 构造方法具有以下 3 个基本特点 : (1) 构造方法名必须与类名相同, 即在上面格式中类名实际上同时也是构造方法名 (2) 构造方法不具有任何返回类型, 即在上面格式中不能在构造方法修饰词与类名之间添加任何单词, 包括关键字 void 如果写上任何返回类型( 包括关键字 void), 则该方法不再是构造方法, 即该方法成为普通的成员方法 (3) 任何一个类都含有构造方法 如果没有显式地定义类的构造方法, 则系统会为该类定义一个默认的构造方法, 这个默认的构造方法不含任何参数 一旦在类中定义了构造方法, 系统不会再创建这个默认的不含参数的构造方法 构造方法的另一个特点是父类与子类的构造方法存在一定的关联, 这一部分的内容将在下一节结合类的继承性进行介绍 在构造方法的定义格式中, 方法的参数列表和方法体两个部分与成员方法的这两部分格式完全相同 方法的参数列表可以包含 0 个 1 个或多个参数, 并且在相邻两个参数之间采用逗号分隔 方法体通常由一些语句组成, 主要用来实现构造方法所需要的功能 在类体部分定义构造方法 成员域和成员方法的出现顺序在语法上没有限制, 不过在实际编程中, 这 3 个部分的出现顺序通常是先定义成员域, 再定义构造方法, 最后编写成员方法 这里允许多个成员方法或构造方法同名, 如果某些成员方法或构造方法同名, 则要求这些方法具有不同的参数列表, 即参数个数不同或参数的数据类型不同 ( 包括数据类型的排列顺序不同 ), 通常不允许存在同名的成员域 创建类的实例对象可以通过 new 运算符和类的构造方法, 其格式为 : new 构造方法名 ( 构造方法调用参数列表 ) 其中,new 是关键字, 表明要创建某一个类的实例对象 ; 构造方法名一般与该构造方法所在的类同名 ; 构造方法调用参数列表由 0 个 1 个或多个表达式组成, 在相邻两个表达式之间采用逗号分隔 这些表达式分别称为构造方法的调用参数, 构造方法的调用参数必须与定义构造方法的参数列表中的参数一一对应, 即调用参数应当与相应参数的数据类型相匹配 例如, 在 Java 的软件包中含有类 Integer, 它是整数类型 (int) 的包装类 类 Integer 含有构造方法 public Integer(int value) 因此, 可以通过 new Integer(11) 创建类 Integer 的实例对象, 该实例对象对应整数 11 在创建类的实例对象之后, 该实例

5 67 第 3 章面向对象程序设计 对象一般会在内存中占用一定的存储单元, 在该存储单元中存储该实例对象的非静态成员域等内容 对于静态成员域参见 3.6 节关于修饰词的介绍 对于非静态的成员域, 每个实例对象一般都会有一套相互独立的数据, 即一套独立的非静态成员域存储单元, 从而不同的实例对象的非静态成员域一般可以拥有不同的值 反过来, 如果不创建实例对象, 则 Java 虚拟机一般不会给非静态成员域分配存储单元 在 Java 的数据类型中除了基本数据类型之外是引用数据类型 引用数据类型变量的类型可以是某一个类, 其定义格式如下 : 类名变量名或带初始化的变量名列表 ; 其中, 变量名或带初始化的变量名列表可以包含一个或多个变量名, 其中每个变量名是一个合法的标识符 如果含有多个变量名, 则变量名或带初始化的变量名之间采用逗号分隔 带初始化的变量名实际上包含变量名和赋值运算, 即等号的左侧是变量名, 等号的右侧是一个表达式, 该表达式的值将成为等号左侧变量的值 例如, 语句 Integer a = new Integer(11); 定义类型为类 Integer 的变量 a 与基本数据类型变量一样, 引用数据类型变量具有 4 个基本属性, 即变量名 数据类型 存储单元和变量值 在上面的示例中, 变量为 a, 数据类型为 Integer, 变量 a 具有一定的存储单元, 在存储单元中存放变量 a 的值 这里变量 a 的值是一个引用值, 它指向上面示例中生成的类 Integer 的实例对象, 其示意图如图 3.1 所示 图 3.1 变量 a 的存储单元示意图前面介绍了类的实例对象的创建方法, 这里介绍类的实例对象的生命周期 当通过 new 运算符和类的构造方法创建类的实例对象时, 首先在内存中创建该实例对象, 接着进行该实例对象的初始化工作 在初始化的过程中, 如果在成员域的定义中含有带初始化的变量名, 则首先运行在成员域的定义中的这些初始化赋值运算, 然后继续运行相应的构造方法完成实例对象的初始化工作 如果有引用指向该实例对象, 则可以通过该引用访问该实例对象的成员域或调用该实例对象的成员方法 设有引用类型的变量指向该实例对象, 则通过该变量访问该实例对象的成员域的格式是 : 变量名. 成员域名在上面的格式中间是一个点 通过该变量调用该实例对象的成员方法的格式是 : 变量名. 成员方法名 ( 成员方法调用参数列表 ) 在上面的格式中间是一个点 这里成员方法调用参数列表由 0 个 1 个或多个表达式组成, 在相邻两个表达式之间采用逗号分隔 这些表达式分别称为成员方法的调用参数, 成员方

6 68 J ava 程序设计 ( 第 2 版 ) 法的调用参数必须与该成员方法所定义的参数列表中的参数一一对应, 即调用参数应当与相应参数的数据类型相匹配 例如, 在类 Integer 中含有成员方法 public int intvalue() 该成员方法返回当前的实例对象所对应的整数值 设 Integer 类型的变量 a 指向类 Integer 的实例对象, 则方法调用 a.intvalue() 返回变量 a 所指向的实例对象所对应的整数值 在 Java 语言中, 对类的实例对象内存的回收是通过垃圾回收机制完成的 垃圾回收机制的基本原理是在适当的时机自动回收不再被 Java 程序所用的内存 这些不再被 Java 程序所用的内存称为垃圾, 因此, 回收内存也称为垃圾回收 对于一个实例对象, 如果没有任何引用指向该实例对象, 则该实例对象所占据的内存是不再被 Java 程序所用的内存, 即垃圾 例如, 语句 Integer a = new Integer(11); 创建类 Integer 的一个实例对象, 变量 a 指向该实例对象 下面的语句 a = null; 将使得变量 a 不再指向该实例对象 如果这时没有其他引用指向该实例对象, 则该实例对象是被废弃的实例对象, 它所占据的内存称为垃圾 当实例对象所占据的内存成为垃圾时, Java 虚拟机一般不会立即回收该垃圾, 而需要等到适当的时机才回收该垃圾 Java 系统自己定义了一套垃圾回收算法, 用来提高垃圾回收的效率 因此,Java 系统并不保证先申请的存储单元会先被释放, 也不保证先成为 垃圾 的存储单元会先被释放 在 Java 系统提供的类 System 中含有成员方法 public static void gc() 调用该成员方法可以向 Java 虚拟机申请尽快进行垃圾回收, 但不能保证 Java 虚拟机会立即进行垃圾回收 因为这个成员方法是类 System 的静态成员方法, 所以可以通过下面的方式 System.gc(); 直接调用该成员方法 对于静态成员方法的介绍参见 3.6 节 在所有的类中实际上都会含有成员方法 protected void finalize() throws Throwable 这个成员方法是类 java.lang.object 的成员方法 其他类通常会继承类 java.lang.object 的这个成员方法 这是类的继承性的一种体现, 关于继承性的内容参见 3.2 节 在实例对象所占据的内存即将被回收之前通常会调用该实例对象的 finalize 成员方法, 但是 Java 系统不保证在回收实例对象所占据的存储单元之前一定会调用 finalize 成员方法 因此, 程序不

7 69 第 3 章面向对象程序设计 应当依赖于 finalize 成员方法来统计程序对内存资源占用的情况 综上所述, 类的实例对象的生命周期包括实例对象的创建 实例对象的使用 实例对象的废弃以及垃圾的回收 下面给出一个说明实例对象生命周期的例程, 例程的源文件名为 J_Finalize.java, 其内容如下 : J_Finalize.java 开发者 : 雍俊海 简介 : 说明实例对象生命周期的例程 class J_Book public int m_id; 书的编号 public J_Book(int i) m_id = i; } J_Book 构造方法结束 protected void finalize() switch (m_id) case 1: System.out.print(" 飘 "); break; case 2: System.out.print(" Java 程序设计教程 "); break; case 3: System.out.print(" 罗马假日 "); break; default: System.out.print(" 未知书籍 "); break; } switch 语句结束 System.out.println(" 所对应的实例对象存储单元被回收 "); } 方法 finalize 结束 } 类 J_Book 结束 public class J_Finalize

8 70 J ava 程序设计 ( 第 2 版 ) public static void main(string args[]) J_Book book1=new J_Book(1); new J_Book(2); new J_Book(3); System.gc(); 申请立即回收垃圾 } 方法 main 结束 } 类 J_Finalize 结束编译命令为 : javac J_Finalize.java 执行命令为 : java J_Finalize 最后执行的结果是在控制台窗口中输出以下内容 : 罗马假日 所对应的实例对象存储单元被回收 Java 程序设计教程 所对应的实例对象存储单元被回收在上面的例程中, 类 J_Finalize 定义了一个成员方法 main 成员方法 main 是一个特殊的成员方法, 是 Java 应用程序的入口, 其定义格式如下 : public static void main(string 参数变量名 []) main 方法体 } 其中, 参数变量名应当是一个合法的标识符, 这里参数变量的类型是字符串数组类型,main 方法体通常由一些语句组成 在运行 Java 应用程序时, 通常是运行成员方法 main 中的各个语句 在上面的例程中, 成员方法 main 的参数变量名是 args 在成员方法 main 中, 前 3 个语句分别创建类 J_Book 的一个实例对象 每个实例对象含有一个成员域 m_id, 用来表示书的编号 在创建实例对象的过程中, 通过类 J_Book 的构造方法完成相应实例对象的初始化工作, 使得这 3 个实例对象所对应的书编号分别为 1 2 和 3 因为后两个实例对象在创建完之后并没有任何引用指向它们, 所以这两个实例对象的存储单元在创建之后立即成为垃圾 接着, 程序通过方法调用 System.gc( ), 申请立即进行垃圾回收 这时, 后两个实例对象所占据的内存可以回收 在回收之前,Java 虚拟机一般会调用这两个实例对象的 finalize 成员方法 对于第 2 个实例对象, 因为它的成员域 m_id 的值是 2, 所以在运行第 2 个实例对象的成员方法 finalize 时, 在控制台窗口中输出以下内容 : Java 程序设计教程 所对应的实例对象存储单元被回收同样, 对于第 3 个实例对象, 在运行该实例对象的成员方法 finalize 时, 在控制台窗口中输出以下内容 :

9 71 第 3 章面向对象程序设计 罗马假日 所对应的实例对象存储单元被回收因为在成员方法 main 中, 变量 book1 一直指向所创建的类 J_Book 的实例对象, 所以变量 book1 所指向的实例对象只能在程序执行完之后回收 这时,Java 虚拟机一般不会调用这个实例对象的 finalize 成员方法 3.2 继承性 面向对象技术的三大特性, 分别是继承性 多态性和封装性 本节介绍继承性,3.3 节介绍多态性,3.5 节介绍封装性 继承性是实现软件可重用性的一种重要手段 在类的定义格式 [ 类修饰词列表 ] class 类名 [extends 父类名 ] [implements 接口名称列表 ] 类体 } 中, 可以通过在关键字 extends 后面添加父类名来指定当前定义的类的父类, 还可以在关键字 implements 的后面添加接口名称列表来指定当前定义的类所实现的各个接口 通过这种方式, 使得当前定义的类可以继承其父类或所实现接口的成员域或成员方法, 即在当前定义的类与其父类或所实现接口之间建立起一种继承关系 这种继承关系具有传递性, 例如类 A 可以拥有父类 B, 同样类 B 可以拥有父类 C, 这时类 C 可以称为是类 A 的父类 本节主要介绍当前定义的类对其父类的一些继承关系, 关于接口的介绍参见 3.7 节的内容 如果在类的定义中不含选项 extends 父类名, 则 Java 虚拟机一般会自动给当前定义的类添加默认的选项 extends java.lang.object 这样, 除了类 java.lang.object 之外, 任何类都有父类, 而且类 java.lang.object 是除了它自身之外的所有类的父类 如果在当前定义的类中含有选项 extends 父类名, 则由该选项指定的父类是当前定义的类的直接父类, 否则当前定义的类的直接父类是类 java.lang.object 因为在选项 extends 父类名 中只能指定一个父类名, 所以每个类 ( 类 java.lang.object 除外 ) 有且仅有一个直接父类 这样通过继承关系, 可以将 Java 的所有类用一个树状的层次结构表示出来, 而且其根部是类 java.lang.object 在类的定义中, 当前定义的类与其直接父类之间在构造方法方面存在约束关系, 即当前定义的类的构造方法必须调用其直接父类的构造方法, 而且该调用语句必须是当前定义的类的构造方法的第一条语句, 其调用格式是 : super( 调用参数列表 ); 其中,super 是关键字, 表示直接父类的构造方法 这里的调用参数列表必须与其直接父类的某个构造方法的参数列表相匹配, 即在调用参数列表中的调用参数与在构造方法参数列表中的参数一一对应, 并且调用参数应当与相应参数的数据类型相匹配 如果在直接父类中不含与当前调用相匹配的构造方法, 则将在编译时出现编译错误 如果在当前定义的类的构造方法中没有显式地写上调用父类构造方法的语句, 则 Java 虚拟机一般会自动在当前

10 72 J ava 程序设计 ( 第 2 版 ) 定义的类的构造方法的第一条语句前自动地 隐式地添加调用不含任何参数的直接父类构造方法的语句, 即结果使得当前定义的类的构造方法的第一条语句实际上为 super(); 虽然这条语句没有显式地出现在源程序中 这里需要注意的是, 如果这时在直接父类中没有不含任何参数的构造方法, 则将在编译时出现编译错误 下面给出一个职工与教师之间的继承性例程, 例程的源文件名为 J_Teacher.java, 其内容如下 : J_Teacher.java 开发者 : 雍俊海 简介 : 职工与教师之间的继承性例程 class J_Employee public int m_workyear; 工作的年限 public J_Employee() m_workyear = 1; } J_Employee 构造方法结束 } 类 J_Employee 结束 public class J_Teacher extends J_Employee public int m_classhour; 授课的课时 public J_Teacher() m_classhour = 96; } J_Teacher 构造方法结束 public void mb_printinfo() System.out.println(" 该教师的工作年限为 " + m_workyear); System.out.println(" 该教师授课的课时为 " + m_classhour); } 方法 mb_printinfo 结束 public static void main(string args[])

11 73 第 3 章面向对象程序设计 J_Teacher tom = new J_Teacher(); tom.mb_printinfo(); } 方法 main 结束 } 类 J_Teacher 结束编译命令为 : javac J_Teacher.java 执行命令为 : java J_Teacher 最后执行的结果是在控制台窗口中输出以下内容 : 该教师的工作年限为 1 该教师授课的课时为 96 在上面的例程中, 类 J_Employee 是类 J_Teacher 的直接父类, 是表示职工的类 ; 类 J_Teacher 是类 J_Employee 的子类, 是表示教师的类 因为新加入的职工的工作年限一般为 1 年, 所以在类 J_Employee 的构造方法中将新创建的实例对象的工作年限 m_workyear 初始化为 1 因为教师也是职工, 所以这里表示教师的类继承自表示职工的类 例如, 教师类通过继承也具有工作年限这一属性 因此, 类 J_Teacher 的成员方法 mb_printinfo 使用了其直接父类的成员域 m_workyear 教师一般需要授课, 每年授课的课时一般是 96 学时 这里在类 J_Teacher 的构造方法中将新创建的实例对象的每年授课的课时 m_classhour 初始化为 96 虽然在类 J_Teacher 的构造方法中没有显式地调用其直接父类的构造方法, 但是 Java 虚拟机一般会自动地 隐式地调用其直接父类的不含任何参数的构造方法 因此, 教师的工作年限 m_workyear 也会被初始化为 1 在子类与父类之间可以进行类型转换, 其转换规则如下 : (1) 第一种转换是隐式类型转换, 通常用于将类型为子类型的数据转换成为类型为其父类型的数据, 这时不需要强制类型转换运算符 ( ) 例如, 将子类的变量直接赋值给父类的变量 假设父类 J_Employee 和子类 J_Teacher 已经按照上面的例程定义, 则下面的语句是一个示例 : J_Teacher tom = new J_Teacher( ); J_Employee a = tom; 在上面的语句中, 将类型为子类 J_Teacher 的变量 tom 直接赋值给类型为父类 J_Employee 的变量 a 当然, 在类型转换时还可以加上强制类型转换运算符 ( ) 例如, 下面的语句 : System.out.println( ((J_Employee)tom).m_workYear ); 先进行类型转换, 将子类 J_Teacher 类型转换为父类 J_Employee 类型, 再调用父类 J_Employee 的成员域, 结果在控制台窗口中输出教师 tom, 或者说职工 tom 的工作年限 这里需要注意的是, (J_Employee)tom 外边的圆括号是不可以去掉的, 即下面的类型

12 74 J ava 程序设计 ( 第 2 版 ) 转换 (J_Employee)tom.m_workYear 实际上是将 tom.m_workyear 的类型转换为 J_Employee 类型 因为 tom.m_workyear 的类型是整数 (int) 类型, 而 J_Employee 类型是引用类型, 所以这种类型转换将产生编译错误 (2) 第二种转换是显式类型转换, 通常用在将类型为父类型的数据转换成为类型为子类型的数据, 这时需要强制类型转换运算符 ( ) 例如, 将父类的变量直接赋值给子类的变量 假设父类 J_Employee 和子类 J_Teacher 已经按照上面的例程定义, 则下面的语句是一个示例 : J_Teacher tom = new J_Teacher(); J_Employee a = tom; J_Teacher b = (J_Teacher) a; 在上面的语句中, 将类型为父类 J_Employee 的变量 a 通过强制类型转换运算符转换成为子类 J_Teacher 的类型, 再赋值给类型为子类 J_Teacher 的变量 b 这里强制类型转换运算符 ( ) 是必需的, 否则将出现编译错误 这里需要注意的是, 下面的语句在编译时不会出现错误, 但在运行时会出现类型转换错误 : J_Employee a = new J_Employee(); J_Teacher b = (J_Teacher) a; 因为无法从变量 a 所指向的实例对象中得到其子类 J_Teacher 的实例对象, 即上面的语句虽然在语法上是正确的, 但在实际运行中是行不通的 (3) 如果两个类型不存在子类型与父类型之间的关系, 则一般不能进行类型转换 例如, 假设类 J_Teacher 已经按照上面的例程定义, 则下面的语句 J_Teacher tom = new J_Teacher(); System.out.println((String)tom); 将产生编译错误, 因为类 J_Teacher 与类 String 之间不存在子类型与父类型的关系 前面介绍了子类型与父类型之间的关系, 这里介绍子类的实例对象与父类的实例对象之间的关系 可以认为子类的实例对象同时也是父类的实例对象, 但由父类的构造方法创建的实例对象一般不是子类的实例对象 判断一个引用类型表达式所指向的实例对象是否是某种引用类型的实例对象可以通过 instanceof 运算符进行判断, 其格式为 : 引用类型表达式 instanceof 引用类型运算结果返回的是一个布尔值 当引用类型表达式不是 null 并且所指向的实例对象是指定引用类型的实例对象时返回 true, 否则返回 false 例如, 假设父类 J_Employee 和子类 J_Teacher 已经按照上面的例程定义, 并且变量 a b 和 c 已经按照下面的方式定义 : J_Teacher a = new J_Teacher(); J_Employee b = new J_Employee();

13 75 第 3 章面向对象程序设计 J_Employee c = a; 则表达式 a instanceof J_Teacher 返回 true, 因为变量 a 指向的实例对象是类 J_Teacher 的实例对象 表达式 a instanceof J_Employee 返回 true, 因为变量 a 指向的实例对象是类 J_Teacher 的实例对象, 同时也可以认为是其父类 J_Employee 的实例对象 表达式 b instanceof J_Teacher 返回 false, 因为变量 b 指向的实例对象是类 J_Employee 的实例对象, 不能认为是其子类 J_Teacher 的实例对象 表达式 c instanceof J_Employee 返回 true, 因为变量 c 指向的实例对象实际上是类 J_Teacher 的实例对象, 同时也可以认为是其父类 J_Employee 的实例对象 表达式 c instanceof J_Teacher 返回 true, 因为变量 c 指向的实例对象实际上是类 J_Teacher 的实例对象 这里 instanceof 运算符可以用在引用类型转换中, 即先判断一个引用表达式所指向的实例对象是否是目标类型的实例对象, 如果确认是, 再进行类型转换, 从而避免引用类型转换的运行时错误 例如, 语句 J_Teacher b = (J_Teacher) a; 可以改写成 if (a instanceof J_Teacher) b = (J_Teacher) a; else b = new J_Teacher(); 这样, 如果在上面语句之前已经定义 J_Employee a = new J_Employee(); 则表达式 (a instanceof J_Teacher) 返回 false, 从而不会进行强制类型转换 b=(j_teacher) a, 因此不会出现引用类型转换的运行时错误 如果在上面修改的语句之前已经定义 J_Teacher c = new J_Teacher(); J_Employee a = c; 则表达式 (a instanceof J_Teacher) 返回 true, 从而可以进行强制类型转换 b=(j_teacher) a, 而且编译与运行均不会出现引用类型转换的错误

14 76 J ava 程序设计 ( 第 2 版 ) 3.3 多态性 多态性是面向对象技术的三大特征之一, 也是实现软件可重用性的手段之一 它使继承特性更加灵活, 并使程序具有良好的可扩展性 多态性指的是在类定义中出现了多个构造方法或多个同名的成员方法 对于同名的成员方法, 多态性还包括在当前定义的类型中出现了与其父类型的成员方法同名的成员方法 多态性包括两种类型, 即静态多态性和动态多态性 这里需要注意的是, 当在类定义中出现了同名的成员域时不仅与多态性没有关系, 而且一般是不提倡的 如果在当前定义的类的类体中出现了同名的成员域, 则程序一般无法通过编译 ; 如果在当前定义的类的类体中出现了与其父类的成员域同名的成员域, 则程序可以通过编译, 但是一般不提倡出现这种情况 静态多态性 静态多态性指的是在同一个类中同名方法在功能上的重载 (overload) 这也包括一个类对其父类同名方法在功能上的重载, 而且在方法声明的形式上要求同名的方法具有不同的参数列表 这里的方法可以是成员方法, 也可以是构造方法 不同的参数列表指的是方法的参数个数不同 参数的数据类型不同或者参数的数据类型的排列顺序不同 这样,Java 虚拟机在编译时可以根据不同的参数列表识别不同的方法, 而且在方法调用中可以根据调用参数列表与方法定义的参数列表匹配确定实际所调用的方法 一般建议, 重载的方法应当具有相似的功能, 这样方便用户理解程序, 即增加程序的可读性, 便于程序的维护 下面给出一个静态多态性例程, 例程的源文件名为 J_Student.java, 其内容如下 : J_Student.java 开发者 : 雍俊海 简介 : 静态多态性例程 public class J_Student public int m_id; 学号 public int m_age; 年龄 public J_Student() mb_setdata( , 19); } J_Student 构造方法结束 public J_Student(int id, int age)

15 77 第 3 章面向对象程序设计 mb_setdata(id, age); } J_Student 构造方法结束 public void mb_setdata(int id, int age) m_id = id; m_age = age; } 方法 mb_setdata 结束 public void mb_setdata(int id) m_id = id; } 方法 mb_setdata 结束 public static void main(string args[]) J_Student jack = new J_Student(); jack.mb_setdata( ); J_Student lisa = new J_Student(); lisa.mb_setdata( , 18); System.out.print("Jack 的学号是 " + jack.m_id); System.out.println(", 年龄是 " + jack.m_age); System.out.print("Lisa 的学号是 " + lisa.m_id); System.out.println(", 年龄是 " + lisa.m_age); } 方法 main 结束 } 类 J_Student 结束编译命令为 : javac J_Student.java 执行命令为 : java J_Student 最后执行的结果是在控制台窗口中输出以下内容 : Jack 的学号是 , 年龄是 19 Lisa 的学号是 , 年龄是 18 在上面的例程中, 构造方法和成员方法 mb_setdata 都采用了静态多态性, 即上面出现了互不冲突的多个构造方法和多个成员方法 mb_setdata 这样, 在方法调用 jack.mb_setdata( ); 时,Java 虚拟机会自动根据调用参数列表查找与其相匹配的方法 public void mb_setdata(int id)

16 78 J ava 程序设计 ( 第 2 版 ) 同样,Java 虚拟机自动根据调用参数列表确定方法调用 lisa.mb_setdata( , 18); 调用的是成员方法 public void mb_setdata(int id, int age) 因为它们不仅参数个数相同, 而且类型也相匹配 这里需要注意的是, 如果在上面例程的类 J_Student 定义中增加成员方法 public void mb_setdata(int age) m_age = age; } 方法 mb_setdata 结束则将出现编译错误, 因为这个新增的成员方法与原有的成员方法 public void mb_setdata(int id) 冲突 这两个成员方法具有相同的参数个数, 而且对应的参数类型也相同 Java 虚拟机实际上无法区分这两个成员方法, 虽然这两个成员方法的参数变量名不同, 但是在方法调用中并没有提供在方法定义的参数列表中的参数变量名, 从而 Java 虚拟机实际上无法根据参数变量名区分这两个成员方法 动态多态性 动态多态性指的是在子类和父类的类体中均定义了具有基本相同声明的非静态成员方法 所谓非静态成员方法指的是在成员方法定义中成员方法的声明不含方法修饰词 static 这时也称为子类的成员方法对其父类基本相同声明的成员方法的覆盖(override) 这里, 基本相同声明的成员方法要求子类的成员方法和其父类对应的成员方法具有相同的方法名 相同的参数个数, 对应参数的类型也相同, 而且子类的成员方法应当比其父类对应的成员方法具有相同或者更广的访问控制方式 成员方法的访问控制方式由定义该成员方法的方法修饰词确定 成员方法的访问控制方式共有 4 种模式, 即公共模式 ( 对应方法修饰词 public) 保护模式( 对应方法修饰词 protected) 默认模式和私有模式( 对应方法修饰词 private) 如果定义成员方法的方法修饰词不含关键字 public protected 和 private, 则该成员方法的访问控制方式采用默认模式 在这 4 种模式中, 公共模式具有最大范围的访问控制权限, 私有模式具有最小范围的访问控制权限, 保护模式的访问控制范围比默认模式的大 对访问控制方式的具体介绍参见 3.5 节封装性的内容 下面给出一个职工与教师之间的动态多态性例程, 例程的源文件名为 J_Teacher.java, 其内容如下 : J_Teacher.java

17 79 第 3 章面向对象程序设计 开发者 : 雍俊海 简介 : 职工与教师之间的动态多态性例程 class J_Employee public int m_workyear; 工作的年限 public J_Employee() m_workyear = 1; } J_Employee 构造方法结束 public void mb_printinfo() System.out.println(" 该职工的工作年限为 " + m_workyear); } 方法 mb_printinfo 结束 } 类 J_Employee 结束 public class J_Teacher extends J_Employee public int m_classhour; 授课的课时 public J_Teacher() m_classhour = 96; } J_Teacher 构造方法结束 public void mb_printinfo() System.out.println(" 该教师的工作年限为 " + m_workyear); System.out.println(" 该教师授课的课时为 " + m_classhour); } 方法 mb_printinfo 结束 public static void main(string args[]) J_Employee a = new J_Employee(); a.mb_printinfo(); a = new J_Teacher(); a.mb_printinfo(); } 方法 main 结束 } 类 J_Teacher 结束 编译命令为 : javac J_Teacher.java

18 80 J ava 程序设计 ( 第 2 版 ) 执行命令为 : java J_Teacher 最后执行的结果是在控制台窗口中输出以下内容 : 该职工的工作年限为 1 该教师的工作年限为 1 该教师授课的课时为 96 在上面的例程中, 类 J_Employee 是类 J_Teacher 的父类 在类 J_Teacher 和类 J_Employee 的类体中均定义了具有相同声明的成员方法 : public void mb_printinfo() 这里类 J_Teacher 的成员方法 mb_printinfo 是对其父类 J_Employee 的具有相同声明的成员方法的覆盖, 这里分析在类 J_Teacher 的成员方法 main 中的各条语句 第一条语句首先定义了类型为 J_Employee 的变量 a, 它指向由 new 运算符及类 J_Employee 的构造方法创建的实例对象 第二条语句通过变量 a 调用成员方法 mb_printinfo, 这时调用的是类 J_Employee 的成员方法 mb_printinfo 第三条语句使得变量 a 指向由 new 运算符及类 J_Teacher 的构造方法创建的实例对象 这里存在类型转换, 这是允许的, 因为变量 a 的类型为类 J_Employee, 而类 J_Employee 是类 J_Teacher 的父类 第四条语句通过变量 a 调用成员方法 mb_printinfo, 这时调用的是类 J_Teacher 的成员方法 mb_printinfo 从这可以看出虽然变量 a 类型为类 J_Employee, 但 Java 虚拟机仍然能够自动识别出变量 a 所指向的实例对象的实际类型, 并根据其实际类型调用相应的成员方法 这样, 通过动态多态性使得可以通过父类型的引用调用子类型的成员方法 这里要求该父类型的引用所指向的实例对象实际上是其子类型的实例对象, 而且调用的子类型的成员方法是对其父类型同名成员方法的覆盖 这种特性为大型软件程序设计实现可扩展性提供了一定的便利 因为存在类型转换机制, 从而造成无法在编译时识别一个引用表达式所指向的实例对象是该引用表达式的类型的实例对象, 还是其子类型的实例对象, 所以在动态多态性的方法调用中无法在编译时识别具体调用的成员方法, 而这一般需要在运行时才能被 Java 虚拟机识别 这是动态多态性和静态多态性之间的区别之一 由于动态多态性使得子类型的成员方法屏蔽了父类型的被覆盖的成员方法, 这会引发一个问题, 即如何在子类型的成员方法中调用父类型的被覆盖的成员方法 在 Java 语言中通过关键字 super 可以处理这一问题, 下面介绍关键字 super 的用途 (1) 在子类型的非静态成员方法中访问其父类型的成员域, 其格式为 : super. 父类型的成员域 ; 如果在子类型的类型体中定义了与该成员域同名的成员域或在当前非静态成员方法中定义了与该成员域同名的局部变量, 则通过上面的方法可以解决同名变量的屏蔽问题 否则, 在上面的格式中, super. 实际上是可以去掉的, 其效果一样 这里被访问的父类型的成员域可以是静态的, 也可以是非静态的 (2) 在子类型的非静态成员方法中调用其父类型的成员方法, 其格式为 :

19 81 第 3 章面向对象程序设计 super. 父类型的成员方法 ( 调用参数列表 ); 这里所调用的父类型的成员方法可以是在父类型中被覆盖的成员方法, 这时实际调用的成员方法是父类型的成员方法 这里被调用的父类型的成员方法可以是静态的, 也可以是非静态的 (3) 在子类的构造方法的第一条语句处调用其父类的构造方法, 其格式为 : super( 父类构造方法的调用参数列表 ); 与关键字 super 相对的关键字是 this this 的用法与 super 的用法相似, 只是它调用的是同一个类的成员域或成员方法 关键字 this 用在当前类的非静态成员方法中, 其使用格式为 : 或者 this. 当前类的成员域 ; this. 当前类的成员方法 ( 调用参数列表 ); 上面的第一种格式主要是为了解决局部变量与成员域同名而造成的屏蔽问题 但实际上, 一般不提倡局部变量与成员域变量同名, 因此这种方法并不常用 如果一定要采用这种方法, 则往往会增加程序出错的可能性, 降低程序的可读性, 导致程序维护成本的提高 因此, 这里关键字 this 基本上是可以省略的, 而且在省略之后其效果是一样的 这里需要注意的是, 动态多态性只针对非静态的成员方法, 即静态的成员方法不具有 动态多态性 例如, 假设在子类和父类的类体中均定义了具有完全相同声明的静态成员方法, 而且类型为父类的变量 a 指向子类的实例对象, 则通过变量 a 调用该静态成员方法将调用在父类的类体中定义的静态成员方法, 而不是在子类的类体中定义的静态成员方法 3.4 包 用户可以将一组相关的类或接口封装在包 (package) 里, 从而更好地管理已经开发的 Java 代码 这里的包 (package) 也可以称为软件包 创建新的包或者将新定义的类 接口或者枚举类型加入到自定义的包中, 可以采用包 (package) 声明语句 这里包声明 语句要求是定义类或者接口 ( 接口的定义参见 3.7 节 ) 或者枚举 ( 枚举的定义参见 5.2 节 ) 类型的 Java 源程序文件的第一条语句, 而且必须是该文件的第一条语句 包声明语句的格式是 : package 包名 ; 其中, 包名可以是一个标识符, 也可以由若干个标识符通过句点. 连接而成 通常建议 采用后一种形式定义包名, 其中包名的前几个标识符是所在单位的 Internet 域名的倒序, 最后一个标识符是一个可以概括该软件包功能的标识符 例如 : package cn.edu.tsinghua.universityorganization; 其中, cn.edu.tsinghua 是清华大学网址域名的逆序, 最后一个标识符说明该软件包的

20 82 J ava 程序设计 ( 第 2 版 ) 功能 编译含有包声明语句的 Java 源程序文件的格式是 : javac -d 路径名 Java 源程序文件名其中,Java 源程序文件名必须是包括后缀.java 的源程序文件名, 路径名指定软件包的根路径 如果软件包的根路径是当前路径, 则路径名可以是一个句点. 在 Java 语言中软件包是以目录的形式进行管理的 如果在包声明语句中的包名只含有一个标识符, 则在编译之后生成的扩展名为.class 的文件位于软件包根路径的下一级路径下, 其中下一级路径的名称是包名 如果在包声明语句中的包名含有多个标识符, 则在编译之后生成的扩展名为.class 的文件位于软件包根路径下面的多级子目录下, 其中各级路径名称依次由组成包名的各个标识符指定 例如, 设需要编译的 Java 源程序文件为 J_Teacher.java, 并且期望的软件包根路径是当前路径, 则编译命令为 : javac -d. J_Teacher.java 设在 Java 源程序文件 J_Teacher.java 中含有包声明语句 package cn.edu.tsinghua.universityorganization; 则新生成的 J_Teacher.class 文件在当前路径下面的子路径 cn\edu\tsinghua\university- Organization ( 对于 Windows 系列的操作系统 ) 或 cn/edu/tsinghua/universityorganization ( 对于 Linux 或 UNIX 系列的操作系统 ) 下 如果需要使用软件包中的类 接口或者枚举等, 则需要导入包的语句 导入包的语句一般是 Java 源程序文件中除了包声明语句之外的最前面的若干条语句 导入包语句的格式有 3 种, 分别为 : (1)import 包名.*; (2)import 包名. 类型名 ; (3)import static 包名. 类型名. 静态成员方法名 ; 在上面的格式中, 第一种格式是将整个包的类 接口或者枚举等导入到当前的程序中 第二种格式是将指定的类型导入到当前的程序中, 其中, 包名指定该类型所在的软件包, 类型名指定具体的类 接口或者枚举等类型 第三种格式是将指定的静态成员方法导入到当前的程序中, 其中, 包名指定该静态成员方法所在的软件包, 类型名指定该静态成员方法所在的类型, 静态成员方法名指定具体的静态成员方法 这里需要注意的是, 第三种格式含有关键词 static 导入包语句的使用原则是尽量使用比较后面的导入包语句形式, 否则, 一般会增加程序的内存开销, 并在一定程度上降低程序的编译效率 对于自定义的软件包, 一般建议采用后两种格式 如果需要采用第一种格式, 则要求在当前路径下不能含有相应的后缀为.java 的 Java 源程序文件以及编译生成的后缀为.class 的文件 例如, 设类 J_Teacher 在软件包 cn.edu.tsinghua.universityorganization 中, 则当需要通过导入包语句 import cn.edu.tsinghua.universityorganization.*; 引入类 J_Teacher 时, 在当前路径下不能含有文件 J_Teacher.java 和 J_Teacher.class

21 83 第 3 章面向对象程序设计 这里需要注意的是, 每个软件包都有一个包名, 而且在包与包之间没有嵌套关系, 即任何包都不会包含其他包 例如, 软件包 cn.edu.tsinghua.universityorganization 不是软件包 cn.edu.tsinghua 的子软件包 导入包语句 import cn.edu.tsinghua.*; 不能代替导入包语句 import cn.edu.tsinghua.universityorganization.*; 即前一个导入包语句不会将在软件包 cn.edu.tsinghua.universityorganization 中的各个类型导入到当前的程序中 在导入软件包的过程中, 软件包根路径是由系统变量 classpath 确定的 系统变量 classpath 的值一般是由一些软件包根路径组成, 在相邻的根路径之间采用分号 ; 分隔开 ( 在 Windows 系列的操作系统中 ) 或者采用冒号 : ( 在 Linux 或 UNIX 操作系统中 ) 分隔开 例如, 当系统变量 classpath 的值为.;C:\j2sdk\lib 则软件包的所有可能根路径为当前路径 ( 对应上面的句点. ) 和路径 C:\j2sdk\lib ( 对应上面的 C:\j2sdk\lib ) 如果 Java 程序安装在路径 C:\j2sdk 下, 则 Java 系统提供的软件包在路径 C:\j2sdk\lib 下 当需要导入软件包时,Java 虚拟机从这些根路径中查找软件包 如果无法找到需要的软件包, 则将出现编译错误 当通过导入包语句将一个软件包导入到当前程序之后, 可以直接用在这个软件包中的类名或者接口名或者枚举名等访问这些类或者接口或者枚举等类型 对于第三种形式的导入包语句, 则可以直接用这个静态成员方法名调用该静态成员方法 下面给出一个软件包创建和应用例程 例程由三个源文件组成 第 1 个源文件名为 J_Employee.java, 其内容如下 : J_Employee.java 开发者 : 雍俊海 简介 : 包例程 职工部分 package cn.edu.tsinghua.universityorganization;

22 84 J ava 程序设计 ( 第 2 版 ) public class J_Employee public int m_workyear; 工作的年限 public J_Employee() m_workyear = 1; } J_Employee 构造方法结束 public void mb_printinfo() System.out.println(" 该职工的工作年限为 " + m_workyear); } 方法 mb_printinfo 结束 } 类 J_Employee 结束第 2 个源文件名为 J_Teacher.java, 其内容如下 : J_Teacher.java 开发者 : 雍俊海 简介 : 包例程 教师部分 package cn.edu.tsinghua.universityorganization; import cn.edu.tsinghua.universityorganization.j_employee; public class J_Teacher extends J_Employee public int m_classhour; 授课的课时 public J_Teacher() m_classhour = 96; } J_Teacher 构造方法结束 public void mb_printinfo() System.out.println(" 该教师的工作年限为 " + m_workyear); System.out.println(" 该教师授课的课时为 " + m_classhour); } 方法 mb_printinfo 结束 } 类 J_Teacher 结束

23 85 第 3 章面向对象程序设计 第 3 个源文件名为 J_University.java, 其内容如下 : J_University.java 开发者 : 雍俊海 简介 : 包例程 主程序部分 import cn.edu.tsinghua.universityorganization.j_employee; import cn.edu.tsinghua.universityorganization.j_teacher; public class J_University public static void main(string args[]) J_Employee a = new J_Employee(); a.mb_printinfo(); a = new J_Teacher(); a.mb_printinfo(); } 方法 main 结束 } 类 J_University 结束编译命令依次为 : javac -d. J_Employee.java javac -d. J_Teacher.java javac J_University.java 上面的编译命令一般不能调换顺序, 否则可能出现编译错误, 主要是因为在这个源程序文件定义的类之间存在一定的依赖关系 执行命令为 : java J_University 最后执行的结果是在控制台窗口中输出以下内容 : 该职工的工作年限为 1 该教师的工作年限为 1 该教师授课的课时为 96 在上面的例程中, 在源程序文件 J_Employee.java 和 J_Teacher.java 中, 通过语句 package cn.edu.tsinghua.universityorganization; 创建软件包 cn.edu.tsinghua.universityorganization, 并分别将类 J_Employee 和类 J_Teacher

24 86 J ava 程序设计 ( 第 2 版 ) 加入到该软件包中 上面的包声明语句在这两个源程序文件中均为第一条语句 在编译命令运行之后, 在路径.\cn\edu\tsinghua\universityOrganization 下增加了两个文件 J_Employee.class 和 J_Teacher.class 在源程序文件 J_University.java 中, 通过语句 import cn.edu.tsinghua.universityorganization.j_employee; import cn.edu.tsinghua.universityorganization.j_teacher; 将软件包 cn.edu.tsinghua.universityorganization 的类 J_Employee 和类 J_Teacher 导入到当前程序中 这两条导入包语句是该文件的头两条语句 这样, 在源程序文件 J_University.java 中, 可以直接通过类名 J_Employee 和 J_Teacher 使用这两个类 如果在源程序文件 J_University.java 中不含导入包语句, 则使用软件包 cn.edu.tsinghua. universityorganization 的类 J_Employee 和类 J_Teacher 一般需要分别通过 cn.edu.tsinghua. universityorganization.j_employee 和 cn.edu.tsinghua.universityorganization.j_teacher 例如, 在去掉源程序文件 J_University.java 的导入包语句之后, 则语句 a = new J_Teacher(); 一般需要改成 a = new cn.edu.tsinghua.universityorganization.j_teacher(); 从这里可以看出, 通过导入包语句可以使源程序变得更加简洁 在 Java 系统提供的软件包中, 有一个软件包比较特殊, 即软件包 java.lang 它是 Java 语言的基本软件包, 即使不通过导入包语句,Java 语言一般也会为所有的 Java 程序自动导入该软件包 软件包 java.lang 提供了 Java 程序所需要的最基本的类和接口, 其中比较常用的类有 Object Boolean Byte Character Double Float Integer Long Short Math String StringBuffer System 等 类 Object 是 Java 语言中除类 Object 本身之外所有类的父类 类 Boolean Byte Character Double Float Integer Long 和 Short 分别是 Java 的 8 种基本数据类型的包装类 类 Math 提供了各种数学计算方法, 例如, 静态方法 Math.abs 计算绝对值 静态方法 Math.cos 计算余弦值 静态方法 Math.sin 计算正弦值 静态方法 Math.tan 计算正切值 静态方法 Math.exp 计算指数值 静态方法 Math.log 计算对数值 静态方法 Math.sqrt 计算平方根等 类 String 是字符串类 类 StringBuffer 可以用来编辑字符序列 类 System 提供了各种与标准输入和标准输出相关的功能, 访问外部定义的属性和环境变量的功能, 加载文件和库的功能, 以及快速复制数组等功能 3.5 封装性 封装性是面向对象技术的基本特征之一 在 Java 语言中, 可以通过封装性使各个模块 ( 对象 ) 的外在表现仅仅为对一些成员域的访问方式和一些成员方法的调用方式, 即屏蔽各个模块 ( 对象 ) 的内部具体实现方式 在 Java 语言中, 封装性是通过访问控制来实现的 所谓访问, 对于类来说, 就是使用该类的成员域或成员方法, 从当前类派生出子类, 或者通过类的构造方法生成实例对象等 ; 对于成员域来说, 就是读取该成员域的值, 或者改变

25 87 第 3 章面向对象程序设计 该成员域的值 ; 对于成员方法来说, 就是调用该成员方法 ; 对于构造方法来说, 就是通过构造方法创建实例对象 如果一个类不是内部类, 则该类的访问控制方式有公共模式 (public) 和默认模式 (default) 两种 这里仅讨论不是内部类的类, 即本节介绍的类均默认不是内部类 对于内部类的介绍参见 3.8 节 如果在类定义的类修饰词列表中包含关键字 public, 则该类的访问控制方式为公共模式 具有公共访问控制模式的类能够被所有软件包使用, 所有的类可以访问具有公共访问控制模式的类 例如, 如果类 J_Teacher 的声明如下 : public class J_Teacher extends J_Employee 则类 J_Teacher 可以被所有的类访问 如果在类定义的类修饰词列表中不包含关键字 public protected 和 private, 则该类的访问控制方式为默认模式 具有默认访问控制模式的类只能在同一个软件包内部使用, 只有在同一个软件包中的类可以访问具有默认访问控制模式的类 例如, 如果类 J_Employee 的声明如下 : class J_Employee 则类 J_Employee 的访问控制方式是默认模式, 可以被在同一个软件包中的类访问, 但不可以被在其他软件包中的类访问 类的成员的访问控制方式有公共模式 (public) 保护模式(protected) 默认模式 (default) 和私有模式 (private)4 种 这里类的成员包括成员域 成员方法和构造方法等 对类的成员的访问首先必须能够访问类, 然后由该成员的访问控制方式确定能否访问该成员 如果在类的成员定义中含有修饰词 public, 则该成员的访问控制方式为公共模式 对于具有公共访问控制模式的成员, 所有能访问该类的类型的定义体 ( 例如, 类体或接口体 ), 包括成员方法, 都能访问该成员 例如, 在下面类 J_Employee 的定义 public class J_Employee public int m_workyear; 工作的年限 public J_Employee() m_workyear = 1; } J_Employee 构造方法结束 public void mb_printinfo() System.out.println(" 该职工的工作年限为 " + m_workyear); } 方法 mb_printinfo 结束 } 类 J_Employee 结束中, 类 J_Employee 的成员域 m_workyear 构造方法 J_Employee 和成员方法 mb_printinfo 在定义时均含有修饰词 public, 即这些成员的访问控制方式均为公共模式 因为类

26 88 J ava 程序设计 ( 第 2 版 ) J_Employee 的访问控制方式也是公共模式, 所以所有软件包的各种类型的成员方法均可以使用类 J_Employee 的这些成员 如果在类的成员定义中含有修饰词 protected, 则该成员的访问控制方式为保护模式 对于具有保护访问控制模式的成员, 在同一个软件包内所有类型的定义体都能访问该成员 如果该成员所在的类的访问控制方式是默认模式, 则在其他软件包中的任何成员方法都不能访问该成员 如果该成员所在的类的访问控制方式是公共模式, 则在其他软件包中能够访问该成员的成员方法一定是该成员所在的类的子类的成员方法 如果在类的成员定义中不含修饰词 public protected 和 private, 则该成员的访问控制方式为默认模式 对于具有默认访问控制模式的成员, 在同一个软件包内所有类型的所有成员方法都能访问该成员, 但是在其他软件包中的任何成员方法都不能访问该成员 如果在类的成员定义中含有修饰词 private, 则该成员的访问控制方式为私有模式 对于具有私有访问控制模式的成员, 只有同一个类的成员方法才能访问该成员 如果该成员所在的类的访问控制方式为公共模式, 则上面的访问控制方式及其允许访问范围如表 3.1 所示 在表 3.1 中, 空白的单元格表示不允许访问 如果该成员所在的类的访问控制方式为默认模式, 则不在同一个软件包的任何成员方法都不允许访问该成员, 即表 3.1 的前三列仍然有效, 但后两列需要增加该成员所在的类的访问控制方式的限制 表 3.1 类成员的访问控制模式及其允许访问的范围 访问控制模式在同一个类内在同一个包内子类所有类 公共模式 (public) 允许访问允许访问允许访问允许访问 保护模式 (protected) 允许访问 允许访问 允许访问 默认模式 (default) 允许访问 允许访问 私有模式 (private) 允许访问 类的成员可以具有 4 种封装属性, 那么如何确定成员应当具有的访问控制模式呢? 这 必须由实际需求或具体程序设计来定 这里给出一种基于程序安全性的设计方案, 其具体方法是先确定允许访问该成员的类有哪些, 这些类与该成员所在的类的关系是什么, 例如是否具有子类与父类的关系, 或者是否在同一个包内 然后, 从表 3.1 中找出能够刚好满足允许访问方式的访问模式 例如, 如果采用默认模式就能满足所需要的访问方式, 则不应当采用保护模式, 这样才能够在访问模式方面最大限度地保证程序的安全性和鲁棒性 另外, 一般建议将类的构造方法的访问控制方式设置成公共模式, 将有特殊限制的成员域的访问控制方式设置成私有模式 这时, 可以添加两个成员方法分别来读取和设置这个具有特殊限制的成员域的值 在这两个成员方法中, 读取该成员域的值的成员方法的名称通常含有字符序列 get, 因此该成员方法通常简称为 get 成员方法 ; 设置该成员域的值的 成员方法的名称通常含有字符序列 set, 因此该成员方法通常简称为 set 成员方法 例如 : public class J_Month private int m_month = 1; 月份, 要求取值为 1~12 public int mb_getmonth()

27 89 第 3 章面向对象程序设计 return m_month; } 方法 mb_getmonth 结束 public int mb_setmonth(int m) if (m<1) m_month=1; else if (m>12) m_month=12; else m_month=m; return m_month; } 方法 mb_setmonth 结束 } 类 J_Month 结束在上面的程序中, 因为类 J_Month 的成员域 m_month 的访问控制方式是私有模式, 所以其他类型的成员方法均无法直接访问成员域 m_month 如果其他类型的成员方法要获取成员域 m_month 的值, 则只能通过 get 成员方法 mb_getmonth 来实现 ; 如果要设置成员域 m_month 的值, 则只能通过 set 成员方法 mb_setmonth 来实现 类 J_Month 的成员方法 mb_setmonth 对一些不合理的参数值进行了修正, 从而保证类 J_Month 的成员域 m_month 的值一定是一个从 1 到 12 的整数 这样, 类 J_Month 的成员域 m_month 可以用来表示月份, 而且不会出现与日常生活不符的月份 3.6 修饰词 abstract static 和 final 本节介绍 3 个常用修饰词, 即 abstract( 抽象 ) static( 静态 ) 和 final( 最终 ) 这 3 个修饰词都是 Java 关键字 在这 3 个修饰词中, 只有 static( 静态 ) 和 final( 最终 ) 两个修饰词可以组合在一起 关键字 abstract 和 static 一般不会同时出现在同一个声明中, 例如, 一个成员方法不可能同时具有抽象 (abstract) 和静态 (static) 属性 同样, 同一个类 接口或者成员方法不可能同时具有抽象 (abstract) 和最终 (final) 两个属性 修饰词 abstract Java 允许类 接口或者成员方法具有抽象属性, 但不允许成员域或者构造方法具有抽 象属性 如果在定义类的类修饰词列表中含有关键字 abstract, 则该类具有抽象属性, 这时, 这个类称为抽象类 无法通过抽象类的构造方法生成抽象类的实例对象 接口总是具有抽 象属性 因此, 不管在定义接口的接口修饰词列表中是否含有关键字 abstract, 该接口都具有 抽象属性 具体关于接口的介绍参见 3.7 节 如果在定义成员方法的方法修饰词列表中含有关键字 abstract, 则该成员方法具有抽象属性 这时, 这个成员方法称为抽象成员方法 抽象 成员方法一般在定义抽象类的类体或者定义接口的接口体中定义 如果一个类不具有抽象属性, 则不能在该类的类体中定义抽象成员方法 抽象成员方法的定义格式与不具有抽象属性的成员方法的定义格式有些不同 抽象成员方法的定义格式为 :

28 90 J ava 程序设计 ( 第 2 版 ) [ 方法修饰词列表 ] 返回类型方法名 ( 方法的参数列表 ); 在上面的格式中, 方法修饰词列表含有关键字 abstract 如果方法修饰词列表还含有其他方法修饰词, 则在相邻方法修饰词之间通过空格隔开 返回类型是该成员方法返回的数据的数据类型 方法的参数列表可以包含 0 个 1 个或多个参数 当在方法的参数列表处除了空格之外不含任何字符时, 表明该参数列表不含任何参数 这里需要注意的是, 不能在方法的参数列表处写上关键字 void, 否则将出现编译错误 在方法的参数列表中, 每个参数的格式是 : 类型参数变量名其中, 类型可以是基本数据类型或引用数据类型, 参数变量名可以是一个合法的标识符 如果在方法的参数列表中包含多个参数, 则在参数之间采用逗号隔开 从上面的定义格式中可以看出抽象成员方法的定义格式与不具有抽象属性的成员方法的定义格式之间的区别 : 除了是否含有方法修饰词 abstract 之外, 抽象成员方法的定义以分号结束, 而且不含方法体 ; 不具有抽象属性的成员方法的定义在成员方法声明之后不能立即出现分号, 而且必须含有方法体 这里介绍抽象类的应用方法 类是实例对象的模板, 可以对实例对象的类型进行归类 然后, 对其中每一个分类进行归纳, 找出该分类中的各个类型的共同特征, 形成一个抽象类型 这里的抽象类型可以是抽象类或者接口 例如, 可以将三角形 四边形和圆等归成同一个分类, 形成形状抽象类 在形状抽象类中, 可以定义三角形 四边形和圆等的共同特性, 如计算面积等 在定义抽象类型之后, 可以将该分类中的各个类型定义成为该抽象类型的子类型 这样, 如果需要生成抽象类型的实例对象, 可以通过这些子类型的构造方法来实现 如果抽象类型的子类型不是抽象类型, 则要求在该子类型的定义中必须定义覆盖抽象类型的所有抽象方法 这里的覆盖指的是在多态性中的覆盖, 即定义除封装性之外相同声明的成员方法 这样根据动态多态性, 可以通过抽象类型的表达式访问抽象类型的成员域以及调用这些被覆盖的成员方法 这样做的优点是可以使程序具有较好的可扩展性 例如, 可以进一步添加某个形状类型, 并将其定义为前面所定义的形状抽象类的子类 对于新定义的子类, 如果只需要调用它的被覆盖的成员方法, 则一般不用修改原有的源程序 这时一般需要添加程序, 用来创建新定义子类的实例对象 下面给出一个抽象类和抽象成员方法程序示例 : abstract class J_Shape public int m_shapeid = 0; 形状的编号 public abstract double mb_getarea(); 计算并返回形状的面积 } 类 J_Shape 结束在上面的抽象类中定义了成员域 m_shapeid 和抽象成员方法 mb_getarea 修饰词 static 这里介绍静态 (static) 属性 除了内部类之外, 类一般不能具有静态属性 类的构造

29 91 第 3 章面向对象程序设计 方法不能具有静态属性, 类的成员域和成员方法可以具有静态属性 如果在定义成员域的域修饰词列表中加上修饰词 static, 则该成员域具有静态属性, 称为静态成员域 ; 如果在定义成员方法的方法修饰词列表中加上修饰词 static, 则该成员方法具有静态属性, 称为静态成员方法 例如, 作为 Java 应用程序入口的 main 成员方法是一个静态成员方法 在 Java 语言中, 类是其实例对象的模板, 同时类本身也可以看作一种对象, 简称为类对象 类的静态成员 ( 例如静态成员域和静态成员方法 ) 隶属于该对象, 可以直接通过类名访问类的静态成员域或者调用类的静态成员方法 直接通过类名访问类的静态成员域的格式是 : 类名. 静态成员域名直接通过类名调用类的静态成员方法的格式是 : 类名. 静态成员方法名 ( 成员方法调用参数列表 ) 下面给出一个有关书籍类的成员域和成员方法的静态属性与非静态属性例程, 例程的源文件名为 J_Book.java, 其内容如下 : J_Book.java 开发者 : 雍俊海 简介 : 有关书籍类的成员域和成员方法的静态属性与非静态属性例程 public class J_Book public int m_id; 书的编号 public static int m_booknumber = 0; 书的总数 public J_Book() m_booknumber++; } J_Book 构造方法结束 public void mb_info() System.out.println(" 当前书的编号是 :" + m_id); } 方法 mb_info 结束 public static void mb_infostatic() System.out.println(" 书的总数是 :" + m_booknumber);

30 92 J ava 程序设计 ( 第 2 版 ) } 方法 mb_infostatic 结束 public static void main(string args[]) J_Book a = new J_Book(); J_Book b = new J_Book(); a.m_id = 1101; b.m_id = 1234; System.out.print(" 变量 a 对应的 "); a.mb_info(); System.out.print(" 变量 b 对应的 "); b.mb_info(); J_Book.mb_infoStatic(); System.out.println(" 比较 (a.m_booknumber==j_book.m_booknumber)" + " 的结果是 :" + (a.m_booknumber==j_book.m_booknumber)); System.out.println(" 比较 (b.m_booknumber==j_book.m_booknumber)" + " 的结果是 :" + (b.m_booknumber==j_book.m_booknumber)); } 方法 main 结束 } 类 J_Book 结束编译命令为 : javac J_Book.java 执行命令为 : java J_Book 最后执行的结果是在控制台窗口中输出以下内容 : 变量 a 对应的当前书的编号是 :1101 变量 b 对应的当前书的编号是 :1234 书的总数是 :2 比较 (a.m_booknumber==j_book.m_booknumber) 的结果是 :true 比较 (b.m_booknumber==j_book.m_booknumber) 的结果是 :true 在上面的例程中, 直接通过 J_Book.m_bookNumber 访问类 J_Book 的静态成员域 m_booknumber, 直接通过 J_Book.mb_infoStatic( ) 调用类 J_Book 的静态成员方法 mb_infostatic 不具有静态属性的成员域和成员方法均不隶属于类本身所对应的对象, 因此, 不能直接通过类名访问这些不具有静态属性的成员域和成员方法 例如, 如果在上面例程的 main 成员方法中添加语句 : System.out.println(J_Book.m_id); 则将引起编译错误, 因为成员域 m_id 不具有静态属性 如果需要访问这些不具有静态属性的成员域和成员方法, 那么一般需要通过类的实例对象 在创建类的实例对象之后, 每个实例对象拥有一套独立的不具有静态属性的成员域

31 93 第 3 章面向对象程序设计 例如, 给一个实例对象的不具有静态属性的成员域赋值一般不会影响到另一个实例对象的成员域 通过指向实例对象的表达式不仅可以访问实例对象的不具有静态属性的成员域和成员方法, 而且可以访问隶属于类对象的静态成员域和成员方法 通过指向实例对象的表达式访问该实例对象的成员域的格式是 : 表达式. 成员域名上面的格式要求表达式指向一个实例对象 在上面的格式中, 成员域可以具有静态属性, 也可以不具有静态属性 因为不具有静态属性的成员域隶属于表达式所指向的实例对象, 所以不同实例对象的成员域所占据的内存是不同的 例如, 在上面例程的 main 成员方法中, 表达式 a.m_id 和 b.m_id 实际上表示两个不同的变量, 它们占据不同的内存, 因此可以具有两个不同的值 因为静态成员域实际上隶属于该实例对象的类本身所对应的对象, 所以通过不同的实例对象和直接通过类访问静态成员域一般具有相同的效果 例如, 在上面例程的 main 成员方法中, 表达式 a.m_booknumber b.m_booknumber 和 J_Book.m_bookNumber 实际上表示同一个变量, 即它们占据相同的内存, 从而拥有相同的值 通过指向实例对象的表达式调用该实例对象的成员方法的格式是 : 表达式. 成员方法名 ( 成员方法调用参数列表 ) 上面的格式要求表达式指向一个实例对象 在上面的格式中, 成员方法可以具有静态属性, 也可以不具有静态属性 因为不具有静态属性的成员方法隶属于表达式所指向的实例对象, 所以调用不同实例对象的不具有静态属性的成员方法可能会产生不同的效果 例如, 在上面例程的 main 成员方法中, 方法调用 a.mb_info( ) 和 b.mb_info( ) 在控制台窗口中输出的内容不同 因为静态成员方法隶属于该成员方法的类本身所对应的对象, 所以通过实例对象与直接通过类名调用静态成员方法实际上具有相同的效果 例如, 在上面例程的 main 成员方法中, 方法调用 a.mb_infostatic( ) b.mb_infostatic( ) 和 J_Book.mb_ infostatic( ) 实际上执行相同的代码, 完成相同的功能 在定义成员方法的方法体中, 如果需要访问同一个类或其父类型的成员域和成员方法, 则基本上可以分别直接通过成员域名和成员方法名 这里介绍访问的条件和访问的形式, 这里父类型包括父类和所实现的接口 在定义不具有静态属性的成员方法的方法体中, 对所定义的成员方法所在的类或其父类型的不具有静态属性的成员域的访问格式是 : (1) 成员域名 (2) this. 成员域名其中,this 是关键字, 指向当前的实例对象 这两种访问方式具有相同的含义, 即均访问当前实例对象的成员域 这里的当前实例对象指的是调用所定义的成员方法的实例对象 例如, 在上面例程的 main 成员方法中, 当进行方法调用 a.mb_info( ) 时, 在成员方法 mb_info 的方法体中的当前实例对象指的是变量 a 所指向的实例对象 ; 当进行方法调用 b.mb_info( ) 时, 在成员方法 mb_info 的方法体中的当前实例对象指的是变量 b 所指向的实例对象 在定义不具有静态属性的成员方法的方法体中, 对所定义的成员方法所在的类

32 94 J ava 程序设计 ( 第 2 版 ) 或其父类型的静态成员域的访问格式是 : (1) 成员域名 (2) 类名. 成员域名其中, 类名是所访问成员域所在的类的名称 这两种访问方式的含义相同, 需要注意的是, 因为静态成员域隶属于类所对应的对象, 所以不能通过格式 : this. 成员域名访问静态成员域, 否则将出现编译错误 在定义不具有静态属性的成员方法的方法体中, 对所定义的成员方法所在的类或其父类型的不具有静态属性的成员方法的访问格式是 : (1) 成员方法名 ( 成员方法调用参数列表 ) (2) this. 成员方法名 ( 成员方法调用参数列表 ) 这两种方法调用的含义相同, 即均调用当前实例对象的成员方法 在定义不具有静态属性的成员方法的方法体中, 对所定义的成员方法所在的类或其父类型的静态成员方法的调用格式是 : (1) 成员方法名 ( 成员方法调用参数列表 ) (2) 类名. 成员方法名 ( 成员方法调用参数列表 ) 其中, 类名是所调用的成员方法所在的类的名称 这两种调用方式的含义相同, 需要注意的是, 因为静态成员方法隶属于类所对应的对象, 所以不能通过格式 : this. 成员方法名 ( 成员方法调用参数列表 ) 访问静态成员方法, 否则将出现编译错误 因为静态成员方法隶属于类所对应的对象, 所以它没有所对应的当前实例对象, 从而在定义静态成员方法的方法体中不能采用关键字 this 在定义静态成员方法的方法体中, 如果需要访问不具有静态属性的成员域和成员方法, 一般需要先创建实例对象, 再通过指向实例对象的表达式访问该实例对象的成员域和成员方法 在定义静态成员方法的方法体中, 对所定义的成员方法所在的类或其父类型的静态成员域的访问格式是 : (1) 成员域名 (2) 类名. 成员域名其中, 类名是所访问成员域所在的类的名称 这两种访问方式的含义相同 在定义静态成员方法的方法体中, 对所定义的成员方法所在的类或其父类型的静态成员方法的调用格式是 : (1) 成员方法名 ( 成员方法调用参数列表 ) (2) 类名. 成员方法名 ( 成员方法调用参数列表 ) 其中, 类名是所调用的成员方法所在的类的名称 这两种调用方式的含义相同 例如, 在作为应用程序入口的 main 成员方法的方法体中, 一般直接访问静态成员域和调用静态成

33 95 第 3 章面向对象程序设计 员方法, 或者通过类名访问该类的静态成员域和静态成员方法, 或者通过指向实例对象的表达式访问该实例对象的成员域和成员方法 修饰词 final 关键字 final( 最终 ) 可以用来修饰不具有抽象属性的类 类的成员域 接口的成员域以及类的不具有抽象属性的成员方法 关键字 final( 最终 ) 不可以用来修饰抽象类 接口 构造方法 抽象成员方法以及接口的成员方法 如果在定义类的类修饰词列表中含有类修饰词 final, 则称该类具有最终属性 具有最终属性的类不能派生出子类, 即该类不能作为父类 例如, 类 java.lang.system 的声明是 public final class System extends Object 这说明类 java.lang.system 具有最终属性, 因此类 java.lang.system 不具有子类 如果在定义成员域的域修饰词列表中加上修饰词 final, 则称该成员域具有最终属性 如果成员域同时具有最终属性和静态属性, 则该成员域只能在定义时赋值, 而且在此之后不能修改该成员域的值了 如果成员域具有最终属性, 但不具有静态属性, 则该成员域只能在定义时或者在构造方法中赋值, 而且只能赋值一次 这样, 具有最终属性的成员域在一定程度上具有固定的值 例如, 在类 java.lang.math 中成员域 PI 的定义为 : public static final double PI = ; 成员域 PI 在定义时赋值, 在此之后就不能再被赋值了 如果在程序中需要使用上面等号右边的常数, 则可以直接用 Math.PI 代替 如果在定义成员方法的方法修饰词列表中加上修饰词 final, 则称该成员方法具有最终属性 这时要求该成员方法不具有抽象属性 如果一个类的成员方法具有最终属性, 则该成员方法不能被当前类的子类的成员方法覆盖 例如, 在定义子类的类体中不能出现与其父类的具有最终属性的成员方法相同声明的成员方法 这样一般可以保证具有最终属性的成员方法所实现的功能不会被其子类改变 3.7 接口 Java 语言不允许一个子类拥有多个直接父类, 即任何子类只能有一个直接父类 但 Java 语言允许一个类实现多个接口, 即在定义类的接口名称列表中可以包含一个或多个接口名称, 从而实现多重继承的特性 接口的定义格式是 : [ 接口修饰词列表 ] interface 接口名 [extends 接口名称列表 ] 接口体 } 其中, 中括号 [ ] 表示其内部的内容是可选项 接口修饰词列表可以包括 0 个 1 个或者多个接口修饰词 如果存在多个接口修饰词, 则在相邻两个接口修饰词之间采用空格隔开 接口修饰词包括 public abstract 和 strictfp 等 接口修饰词 public 表示上面定义的接口

34 96 J ava 程序设计 ( 第 2 版 ) 具有公共的封装访问控制属性, 可以被 Java 的各个软件包使用 如果在上面接口的定义中含有接口修饰词 public, 则接口应当与其所在文件的前缀相同 (Java 源文件的扩展名一定是.java ) 在同一个 Java 源文件中可以包含多个类或接口, 但不能包含两个或两个以上的具有 public 修饰词的类或接口 如果在接口修饰词列表中不含关键字 public protected 和 private, 则上面定义的接口具有默认的封装访问控制属性, 只能在当前的软件包中使用 除非将接口定义在类的内部, 接口一般不能具有 protected 和 private 属性 接口修饰词 abstract 表示上面定义的接口具有抽象属性 因为接口本身就具有抽象属性, 所以接口修饰词 abstract 不是必要的 接口修饰词 strictfp 表明在当前接口中各个浮点数的表示及其运算严格遵循 IEEE 754 算术国际标准 接口名可以是任意的合法标识符 extends 接口名称列表 是可选项 如果包含 extends 接口名称列表 选项, 则在接口名称列表中可以包含一个或多个接口名称, 表明当前定义的接口继承这些给定的接口 如果在接口名称列表中存在多个接口名称, 则在相邻两个接口名称之间采用逗号隔开 在接口名称列表中的接口称为当前接口的父接口, 当前接口称为它们的子接口 在接口体部分可以定义接口的两类成员要素, 即成员域和成员方法 在接口体内部不含构造方法, 因此一般不能直接通过接口生成接口的实例对象 接口的成员域简称为域, 其定义格式为 : [ 域修饰词列表 ] 类型带初始化的变量名列表 ; 其中, 在域修饰词列表可选项中可以包含 public static 和 final 等域修饰词, 但是一般不可以包含 protected 和 private 等关键字 如果存在多个域修饰词, 则在相邻两个域修饰词之间采用空格隔开 即使不具有域修饰词列表或者在域修饰词列表中不包含修饰词 public static 和 final, 接口的成员域也具有 public static 和 final 属性 因此, 接口的所有成员域都具有 public static 和 final 属性 在带初始化的变量名列表中可以包含一个或多个带初始化的变量名, 并且在相邻的带初始化的变量名之间采用逗号隔开 这里带初始化的变量名实际上包含赋值运算, 即等号的左侧是变量的名称, 等号的右侧是一个表示变量的值的表达式 例如, 在接口体内部定义 double PI = ; 或者 public static final double PI = ; 上面两个成员域的定义实际上是等价的, 它们都具有 public static 和 final 属性 接口的成员方法可以简称为方法 接口的成员方法只能是抽象成员方法, 其定义格式为 : [ 方法修饰词列表 ] 返回类型方法名 ( 方法的参数列表 ); 在上面的格式中, 方法修饰词列表中可以含有关键字 public 和 abstract 等修饰词, 但是一般不可以包含 protected private 和 final 等关键字 即使不具有方法修饰词列表或者在方法修饰词列表中不包含修饰词 public 和 abstract, 接口的成员方法也具有 public 和 abstract 属

35 97 第 3 章面向对象程序设计 性 因此, 接口的所有成员方法都具有 public 和 abstract 属性 如果方法修饰词列表中含有多个方法修饰词, 则在相邻方法修饰词之间通过空格隔开 返回类型是该方法返回的数据的数据类型 如果该成员方法不需要返回值, 则应当在返回类型处写上关键字 void 方法的参数列表可以包含 0 个 1 个或多个参数 当在方法的参数列表处除了空格之外不含任何字符时, 表明该参数列表不含任何参数 这里需要注意的是, 不能在方法的参数列表处写上关键字 void, 否则将出现编译错误 在方法的参数列表中, 每个参数的格式是 : 类型参数变量名其中, 类型可以是基本数据类型或引用数据类型, 参数变量名可以是一个合法的标识符 如果在方法的参数列表中包含多个参数, 则在参数之间采用逗号隔开 接口的应用方法非常类似于抽象类, 只是通过接口在一定程度上可以实现多重继承 在接口中可以定义一些具有固定值的静态成员域 另外, 还可以将一些实例对象的类型进行归类, 从而找到它们的共同特征形成接口, 并将这些实例对象的类型定义成为实现该接口的子类型, 例如类 在实现接口的类中, 除了抽象类之外, 要求在该类的类体中定义覆盖该接口的所有成员方法 如果需要生成接口的实例对象, 可以通过实现接口的类的构造方法来实现 根据继承性, 实现接口的类的实例对象也可以被认为是该接口的实例对象 访问接口的静态成员域可以采用下面的格式 : 接口名. 静态成员域名或者表达式. 成员域名其中, 表达式指向一个类型为该接口的实例对象 调用接口的成员方法可以采用下面的格式 : 表达式. 成员方法名 ( 成员方法调用参数列表 ) 其中, 表达式指向一个类型为该接口的实例对象 下面给出一个接口定义的程序示例 : interface J_Shape public static final double PI = ; public abstract double mb_getarea(); 计算并返回形状的面积 } 接口 J_Shape 结束上面的接口中定义了成员域 PI 和抽象成员方法 mb_getarea 3.8 内部类 这里介绍在定义类的类体内部定义的内部类 (inner class) 按照内部类是否含有显式 的类名, 可以将内部类分为实名内部类和匿名内部类 与 3.1 节介绍的类的定义格式一样, 实名内部类的定义格式是 :

36 98 J ava 程序设计 ( 第 2 版 ) [ 类修饰词列表 ] class 类名 [extends 父类名 ] [implements 接口名称列表 ] 类体 } 它是定义在一个类的类体中 内部类所在的类称为外部类 3.1 节介绍的内容在这里基本上适用, 只是内部类既具有非内部类的特性, 又具有一些类的成员的特性 这里介绍实名内部类的一些特性 相对非内部类而言, 实名内部类的封装性增加了保护模式 (protected) 和私有模式 (private), 即在实名内部类的类修饰词列表中可以包含关键字 protected 或者 private 这里的实名内部类可以看作类的一种成员, 因此实名内部类的封装性可以参考 3.5 节关于封装性的介绍, 其中各种访问控制模式的允许访问范围参见 3.5 节的表 3.1 在实名内部类的类修饰词列表中还可以含有关键字 static, 这时实名内部类称为静态实名内部类 如果在定义实名内部类的类修饰词列表中不含关键字 static, 则该实名内部类称为不具有静态属性的实名内部类 对于不具有静态属性的实名内部类, 如果它的成员域具有静态属性, 则必须同时具有最终 (final) 属性 不具有静态属性的实名内部类不能含有具有静态属性的成员方法 在外部类的类体中使用实名内部类, 其类型名称可以直接是实名内部类名 例如, 设实名内部类为 J_Inner, 则在外部类的类体中, 语句 J_Inner b; 定义了类型为实名内部类 J_Inner 的变量 b 如果在外部类之外的其他类的类体中使用该外部类的实名内部类, 其类型名称的格式是 : 外部类名. 实名内部类名例如, 设外部类为 J_Test, 实名内部类为 J_Inner, 则在外部类之外的其他类的类体中, 语句 J_Test.J_Inner b; 定义了类型为 J_Test.J_Inner 的变量 b 这里介绍实名内部类的实例对象的创建方法 创建静态实名内部类的实例对象可以采用以下格式 : new 外部类名. 实名内部类名 ( 构造方法调用参数列表 ) 其中, 构造方法调用参数列表是静态实名内部类的构造方法的调用参数列表 如果上面创建实例对象的语句在外部类的类体中, 则在上面的格式中可以省略 外部类名. 创建不具有静态属性的实名内部类的实例对象可以采用以下格式 : 外部类表达式.new 实名内部类名 ( 构造方法调用参数列表 ) 其中, 外部类表达式是指向外部类实例对象的引用, 构造方法调用参数列表是实名内部类的构造方法的调用参数列表 例如, 设外部类为 J_Test, 实名内部类 J_Inner 不具有静态属性, 并且类 J_Test 和 J_Inner 都具有不含参数的构造方法, 则语句

37 99 第 3 章面向对象程序设计 J_Test a = new J_Test(); J_Test.J_Inner b = a.new J_Inner(); 分别创建了类 J_Test 和 J_Inner 的实例对象, 最终类型为 J_Test.J_Inner 的变量 b 指向该实例对象 这里介绍对实名内部类的成员域和成员方法的访问方式 访问静态实名内部类的静态成员域可以采用以下格式 : 外部类名. 实名内部类名. 静态成员域名如果上面语句是在外部类的类体中, 则在上面格式中可以省略 外部类名. 访问静态实名内部类的不具有静态属性的成员域可以采用以下格式 : 表达式. 成员域名其中, 表达式是指向实名内部类实例对象的引用 调用静态实名内部类的静态成员方法可以采用以下格式 : 外部类名. 实名内部类名. 静态成员方法名 ( 成员方法调用参数列表 ) 如果上面语句是在外部类的类体中, 则在上面格式中可以省略 外部类名. 调用静态实名内部类的不具有静态属性的成员方法可以采用以下格式 : 表达式. 成员方法名 ( 成员方法调用参数列表 ) 其中, 表达式是指向实名内部类实例对象的引用 访问不具有静态属性的实名内部类的静态成员域可以采用以下格式 : 外部类名. 实名内部类名. 静态成员域名如果上面语句是在外部类的类体中, 则在上面格式中可以省略 外部类名. 需要注意的是, 这里的静态成员域一定同时具有最终属性 访问不具有静态属性的实名内部类的不具有静态属性的成员域可以采用以下格式 : 表达式. 成员域名其中, 表达式是指向实名内部类实例对象的引用 调用不具有静态属性的实名内部类的不具有静态属性的成员方法可以采用以下格式 : 表达式. 成员方法名 ( 成员方法调用参数列表 ) 其中, 表达式是指向实名内部类实例对象的引用 这里需要注意的是, 不具有静态属性的实名内部类不能拥有静态成员方法 在实名内部类的成员方法中, 对外部类和内部类的成员域和成员方法的访问格式与 小节介绍的访问格式相类似 下面给出一个实名内部类例程, 例程的源文件名为 J_InnerTest.java, 其内容如下 : J_InnerTest.java

38 100 J ava 程序设计 ( 第 2 版 ) 开发者 : 雍俊海 简介 : 实名内部类例程 class J_Test int m_dataouter = 1; static int m_dataouterstatic= 2; class J_Inner int m_data; static final int m_datastatic = 4; public J_Inner() m_data = 3; } J_Inner 构造方法结束 public void mb_method() System.out.println("m_dataOuter=" + m_dataouter); System.out.println("m_dataOuterStatic=" + m_dataouterstatic); System.out.println("m_data=" + m_data); System.out.println("m_dataStatic=" + m_datastatic); mb_methodouter(); } 方法 mb_method 结束 } 内部类 J_Inner 结束 public void mb_methodouter() System.out.println("mb_methodOuter"); } 方法 mb_methodouter 结束 } 类 J_Test 结束 public class J_InnerTest public static void main(string args[]) J_Test a = new J_Test(); J_Test.J_Inner b = a.new J_Inner(); b.mb_method();

39 101 第 3 章面向对象程序设计 } 方法 main 结束 } 类 J_InnerTest 结束编译命令为 : javac J_InnerTest.java 执行命令为 : java J_InnerTest 最后执行的结果是在控制台窗口中输出以下内容 : m_dataouter=1 m_dataouterstatic=2 m_data=3 m_datastatic=4 mb_methodouter 在上面的例程中, 实名内部类的成员方法 mb_method 可以直接访问外部类 J_Test 的成员域 m_dataouter 静态成员域 m_dataouterstatic 以及成员方法 mb_methodouter 匿名内部类不具有类名, 不能具有抽象和静态属性, 并且不能派生出子类 定义匿名内部类的定义可以采用以下格式 : new 父类型名 ( 父类型的构造方法的调用参数列表 ) 类体 } 在上面的格式中, 父类型可以是一个类, 此时所定义的匿名内部类是该父类型的子类 ; 父类型还可以是一个接口, 此时所定义的匿名内部类是实现该接口的类 如果父类型是类, 则在上面格式中父类型的构造方法的调用参数列表应当与该类的某个构造方法的参数列表相匹配 如果父类型是接口, 则在上面格式中父类型的构造方法的调用参数列表可以不含任何调用参数 因为匿名内部类不含类名, 所以在匿名内部类的类体中一般不能显式地定义构造方法 上面的格式不仅定义匿名内部类, 而且创建匿名内部类的实例对象 它所调用的构造方法实际上是其父类型的与其调用参数相匹配的构造方法, 或者是由 Java 虚拟机自动生成的不含任何参数的构造方法 在匿名内部类的类体内可以定义成员域和成员方法 匿名内部类的成员定义方式与不具有静态属性的实名内部类的成员定义方式基本上相同 如果匿名内部类的成员域具有静态属性, 则必须同时具有最终 (final) 属性 匿名内部类不能含有具有静态属性的成员方法 如果需要使用匿名内部类的实例对象, 可以直接采用上面格式生成的实例对象 另一种方式是通过其父类型的变量, 即先让其父类型的变量指向匿名内部类的实例对象, 再由

40 102 J ava 程序设计 ( 第 2 版 ) 该变量调用被匿名内部类覆盖的成员方法或者父类型的成员方法 对于后一种形式, 除了覆盖父类型的成员方法之外, 该变量无法调用在匿名内部类的类体中定义的其他成员方法 在实际的应用中, 对匿名内部类的使用一般是通过这一种方式, 即利用面向对象的动态多态性的成员方法覆盖机制 匿名内部类常常用在 Java 的图形用户界面程序设计中 下面给出一个父类型为类的匿名内部类例程, 例程的源文件名为 J_InnerClass.java, 其内容如下 : J_InnerClass.java 开发者 : 雍俊海 简介 : 父类型为类的匿名内部类例程 abstract class J_Class int m_data; public J_Class(int i) m_data = i; } J_Class 构造方法结束 public abstract void mb_method(); } 抽象类 J_Class 结束 public class J_InnerClass public static void main(string args[]) J_Class b = new J_Class(5) public void mb_method() System.out.println("m_data=" + m_data); } 方法 mb_method 结束 }; 父类型为类 J_Class 的匿名内部类结束 b.mb_method(); } 方法 main 结束 } 类 J_InnerClass 结束 编译命令为 : javac J_InnerClass.java

41 103 第 3 章面向对象程序设计 执行命令为 : java J_InnerClass 最后执行的结果是在控制台窗口中输出以下内容 : m_data=5 在上面的例程中, 匿名内部类的父类型是类 J_Class 为了更好地理解上面的例程, 下面给出将上面例程转换成为父类型为类的非内部类实现的对照例程, 例程的源文件名仍然为 J_InnerClass.java, 其内容如下 : J_InnerClass.java 开发者 : 雍俊海 简介 : 父类型为类的对照例程 abstract class J_Class int m_data; public J_Class(int i) m_data = i; } J_Class 构造方法结束 public abstract void mb_method(); } 抽象类 J_Class 结束 class J_Anonymity extends J_Class public J_Anonymity(int i) super(i); } J_Anonymity 构造方法结束 public void mb_method() System.out.println("m_data=" + m_data); } 方法 mb_method 结束 } 类 J_Anonymity 结束 public class J_InnerClass

42 104 J ava 程序设计 ( 第 2 版 ) public static void main(string args[]) J_Class b = new J_Anonymity(5); b.mb_method(); } 方法 main 结束 } 类 J_InnerClass 结束上面两个例程的编译命令 执行命令以及执行结果都是相同的 通过上面两个例程的对照, 用户可以更清楚地理解匿名内部类的实现机制 在定义匿名内部类的格式中, new 父类型名 ( 父类型的构造方法的调用参数列表 ) 实际上调用的是匿名内部类的构造方法, 不过这个构造方法是由 Java 虚拟机自动创建的 例如, 在上面的匿名内部类例程中,Java 虚拟机自动创建的匿名内部类例程的构造方法类似于在其对照例程中类 J_Anonymity 的构造方法 通过对照例程可以看出, 该构造方法只是简单地调用在父类型中与调用参数相匹配的构造方法 定义匿名内部类的类体与定义类 J_Anonymity 的类体相比, 除了少了构造方法之外, 其他部分基本上是相同的 匿名内部类在定义中没有显式地写出对其父类型的继承关系, 而在类 J_Anonymity 的定义中直接通过 extends J_Class 说明类 J_Anonymity 是类 J_Class 的子类 下面给出一个父类型为接口的匿名内部类例程, 例程的源文件名为 J_InnerInterface. java, 其内容如下 : J_InnerInterface.java 开发者 : 雍俊海 简介 : 父类型为接口的匿名内部类例程 interface J_Interface public static int m_data = 5; public abstract void mb_method(); } 接口 J_Interface 结束 public class J_InnerInterface public static void main(string args[]) J_Interface b = new J_Interface() public void mb_method()

43 105 第 3 章面向对象程序设计 System.out.println("m_data=" + m_data); } 方法 mb_method 结束 }; 实现接口 J_Interface 的匿名内部类结束 b.mb_method(); } 方法 main 结束 } 类 J_InnerInterface 结束编译命令为 : javac J_InnerInterface.java 执行命令为 : java J_InnerInterface 最后执行的结果是在控制台窗口中输出以下内容 : m_data=5 在上面的例程中, 匿名内部类的父类型是接口 J_Interface 为了更好地理解上面的例程, 下面给出将上面例程转换成为父类型为接口的非内部类实现的对照例程, 例程的源文件名仍然为 J_InnerInterface.java, 其内容如下 : J_InnerInterface.java 开发者 : 雍俊海 简介 : 父类型为接口的对照例程 interface J_Interface public static int m_data = 5; public abstract void mb_method(); } 接口 J_Interface 结束 class J_Anonymity implements J_Interface public void mb_method() System.out.println("m_data=" + m_data); } 方法 mb_method 结束 } 类 J_Anonymity 结束

44 106 J ava 程序设计 ( 第 2 版 ) public class J_InnerInterface public static void main(string args[]) J_Interface b = new J_Anonymity(); b.mb_method(); } 方法 main 结束 } 类 J_InnerInterface 结束上面两个例程的编译命令 执行命令以及执行结果都是相同的 通过上面两个例程的对照, 用户可以更清楚地理解匿名内部类的实现机制 在上面的匿名内部类例程中, 匿名内部类的父类型是接口 在定义匿名内部类的格式中, new 父类型名 ( 父类型的构造方法的调用参数列表 ) 实际上调用的是匿名内部类的构造方法 这里匿名内部类在其对照例程中对应类 J_Anonymity 匿名内部类的构造方法类似其对照例程的类 J_Anonymity 的构造方法, 是由 Java 虚拟机自动创建的不含任何参数的构造方法 定义匿名内部类的类体与在其对照例程中定义类 J_Anonymity 的类体相比, 各个部分基本上是相同的 匿名内部类在定义中没有显式地写出对其父类型的继承关系, 而在类 J_Anonymity 的定义中直接通过 implements J_Interface 说明类 J_Anonymity 是实现接口 J_Interface 的类 上面的两个例程都是通过父类型 ( 即接口 J_Interface) 的变量 b 指向子类型 ( 即匿名内部类或类 J_Anonymity) 的实例对象, 再由变量 b 调用被子类型覆盖的成员方法 mb_method 3.9 变量作用域范围与参数传递方式 本节介绍变量的作用域范围和方法调用的参数传递方式 通过变量可以存储各种数据, 通过方法可以实现一些需要的功能 在 Java 语言中, 方法调用的参数传递方式相对简单一些, 主要采用值传递方式 变量作用域范围 在 Java 语言中, 变量主要包括成员域 成员方法或构造方法的参数变量 在方法体内定义的局部变量 变量作用域范围指的是变量在 Java 程序中的有效范围 变量的作用域范围可以分成全局作用域范围 类作用域范围和块作用域范围 3 种 静态成员域具有全局作用域范围 只要根据 3.5 节的封装性能够访问到该静态成员域, 一般就能使用该静态成员域 例如, 类 java.lang.math 的声明是 public final class Math extends Object 说明类 java.lang.math 的访问控制方式是公共模式 ; 类 java.lang.math 的静态成员域 public static final double PI = ; 的访问控制方式也是公共模式, 因此, 在各个软件包中均可以使用该静态成员域 访问静态成员域的格式是 :

45 107 第 3 章面向对象程序设计 类型名. 静态成员域名 其中, 类型名是该静态成员域所在的类型的名称, 可以是类名或接口名 例如, 可以通过 Math.PI 访问类 java.lang.math 的静态成员域 PI 如果在该类型或其子类型的定义体( 例如, 类体或接口体 ) 内访问该静态成员域, 则在上面格式中可以省略 类型名. 不具有静态属性的成员域具有类作用域范围 在该成员域所在类型或其子类型的不具 有静态属性的成员方法的方法体中可以直接访问不具有静态属性的成员域, 即使成员方法 的定义在成员域的定义前面 例如 : class J_Time public int mb_getmonth() return m_month; 域 m_month 的定义在方法 mb_getmonth 的定义之后 } 方法 mb_getmonth 结束 private int m_month=1; 要求 m_month 从 1, 2,, 12} 中取值 这里省略类体的其他部分 } 类 J_Time 结束 在上面的示例中, 成员域 m_month 的定义在成员方法 mb_getmonth 的定义后面, 这是允许的 不过在编程规范中, 一般要求成员域的定义在成员方法的定义前面 如果在定义成员域时采用带初始化的方式, 则在赋值运算符的右侧表达式中可以含有 在当前成员域定义之前定义的其他成员域 例如 : class J_Time public int m_month = 1; public int m_day = m_month*30; 这里省略类体的其他部分 } 类 J_Time 结束 在上面的示例中, 在定义成员域 m_day 的赋值运算中含有成员域 m_month 这里需要注意的是, 这时不能将定义成员域 m_day 和 m_month 的前后顺序对调, 否则将出现编译错误 例如 : class J_Time public int m_day = m_month*30; 错误 : m_month 还没有定义 public int m_month = 1; 这里省略类体的其他部分 } 类 J_Time 结束 上面的示例会出现编译错误, 因为在定义成员域 m_day 时还没有定义成员域 m_month

46 108 J ava 程序设计 ( 第 2 版 ) 成员方法或构造方法的参数变量以及在方法体内定义的局部变量具有块作用域范围 这里成员方法或构造方法的参数变量以及在方法体内定义的局部变量统称为局部变量 局部变量的作用域从该变量的声明处一直到该变量所在的块的结束处 对于在语句块中定义的局部变量, 因为语句块是由 和 } 括起来的语句序列, 所以该变量的作用域也就止于它所在的语句块的最后一个 } 例如: 语句块开始处 int data=5; System.out.println("data=" + data); } 语句块结束处能够访问上面定义局部变量 data 的范围是从其定义之处开始到上面语句块结束之处 在上面语句块结束之后, 上面所定义的局部变量 data 就不能再被访问到 这时可以认为在上面语句块结束之后没有定义局部变量 data, 除非重新定义一个新的局部变量 data 如果在定义了一个变量的语句块之中并且在定义该变量的语句之后含有嵌套的语句块, 则在嵌套的语句块中的语句可以访问该变量, 这是因为嵌套的语句块是其所在的语句块的一个组成部分 例如 : 语句块开始处 int data=5; System.out.println("data( 外部 )=" + data); 嵌套的语句块开始处 System.out.println("data( 内部 )=" + data); } 嵌套的语句块结束处 } 语句块结束处在成员方法或构造方法的声明处定义的参数变量只能在该成员方法或构造方法的方法体内部使用 在 for 语句的初始化表达式中定义的变量只能在 for 语句中使用 在 for 语句结束之后, 该变量失效 例如 : for (int i=0; i<5; i++) System.out.println("i=" + i); } for 循环结束 System.out.println("i=" + i); 编译错误上面定义的局部变量 i 只能在 for 语句中使用 因此, 上面示例的最后一个语句一般会出现编译错误, 错误原因是在该语句处变量 i 没有定义 在程序设计中, 一般不允许同名的变量具有重叠 ( 包括部分重叠 ) 的作用域范围 在 Java 语言中, 允许局部变量与成员域同名, 允许子类型的成员域与其父类型的成员域同名, 这时将出现同名变量的作用域范围呈现重叠的现象 这时, 可以考虑通过关键字 this 和 super 解决同名变量的作用域范围冲突问题 对于不具有静态属性的成员域, 可以通过 this. 成员域

47 109 第 3 章面向对象程序设计 访问当前类型的成员域, 可以通过 super. 成员域访问当前类型的父类型的不具有静态属性的成员域 对于静态成员域, 可以通过类型名. 静态成员域名访问当前类型的静态成员域 虽然 Java 语言允许出现这些同名变量的作用域范围重叠的情况, 但在实际的程序设计中一般尽量避免出现这种情况 如果出现同名变量的作用域范围重叠的情况, 一般会比较容易引起程序出现错误 下面给出一个同名变量作用域范围重叠情况处理例程, 例程的源文件名为 J_Scope.java, 其内容如下 : J_Scope.java 开发者 : 雍俊海 简介 : 同名变量作用域范围重叠情况处理例程 class J_Time public int data = 3; 这里省略类体的其他部分 } 类 J_Time 结束 public class J_Scope extends J_Time public int data = 2; public void mb_method() int data = 1; System.out.println("data=" + data); System.out.println("this.data=" + this.data); System.out.println("super.data=" + super.data); } 方法 mb_method 结束 public static void main(string args[]) J_Scope a = new J_Scope(); a.mb_method();

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc CHAPTER3 第 3 章 面向对象程序设计 Java 语言是一种面向对象的高级程序语言 应用面向对象语言求解问题的基本思路是 : 首先分析问题并建立相应的对象, 然后通过这些对象以及它们之间的配合解决问题, 其中每个对象在计算机中占用一定的内存, 同时能够完成一定的功能 这种基本思想实际上是模拟现实生活求解问题的一般过程 在现实生活中, 任何一个人或任何一种物体都可以被认为是对象 例如 : 人一般拥有手

More information

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

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

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

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP:  ******************* * 关于 Java 测试试题 ****** ******************* * 关于 Java 测试试题 ******************* 問 1 运行下面的程序, 选出一个正确的运行结果 public class Sample { public static void main(string[] args) { int[] test = { 1, 2, 3, 4, 5 ; for(int i = 1 ; i System.out.print(test[i]);

More information

新・解きながら学ぶJava

新・解きながら学ぶJava 481! 41, 74!= 40, 270 " 4 % 23, 25 %% 121 %c 425 %d 121 %o 121 %x 121 & 199 && 48 ' 81, 425 ( ) 14, 17 ( ) 128 ( ) 183 * 23 */ 3, 390 ++ 79 ++ 80 += 93 + 22 + 23 + 279 + 14 + 124 + 7, 148, 16 -- 79 --

More information

1 下列类头定义中, 正确的是 面向对象程序设计网络课程 A class x { } B public x extends y { } C public class x extends y {.} D class x extends y implements y1 { } 2 现有两个类 A B,

1 下列类头定义中, 正确的是 面向对象程序设计网络课程 A class x { } B public x extends y { } C public class x extends y {.} D class x extends y implements y1 { } 2 现有两个类 A B, 1 下列类头定义中, 正确的是 A class x B public x extends y C public class x extends y. D class x extends y implements y1 2 现有两个类 A B, 以下描述中表示 B 继承自 A 的是 (D ) A) class A extends B B) class B implements A C) class A

More information

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

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d =

More information

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class

More information

OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票

OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票 复习 创建对象 构造函数 函数重载 : 函数 = 函数名 + 参数列表 public class MyType { int i; double d; char c; void set(double x)

More information

软件工程文档编制

软件工程文档编制 实训抽象类 一 实训目标 掌握抽象类的定义 使用 掌握运行时多态 二 知识点 抽象类的语法格式如下 : public abstract class ClassName abstract void 方法名称 ( 参数 ); // 非抽象方法的实现代码 在使用抽象类时需要注意如下几点 : 1 抽象类不能被实例化, 实例化的工作应该交由它的子类来完成 2 抽象方法必须由子类来进行重写 3 只要包含一个抽象方法的抽象类,

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

模板

模板 制作人 : 张刚 目录 类和对象 面向对象程序设计基本特征 类的声明 构造方法 成员变量和方法 封装 继承 多态 包 访问控制 final static 抽象类和接口 内部类 沈阳工业大学软件学院 Java 课程教研组 Page 2 核心知识点 类 对象 三个基本特征 类的基本结构 成员变量 构造方法 成员方法 类实例 对象创建和操作 沈阳工业大学软件学院 Java 课程教研组 Page 3 1.

More information

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

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class - Table.class

More information

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢   学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 Email: 51141201063@ecnu.cn 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Java 类型 引用 不可变类型 对象存储位置 作用域 OOP

More information

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 月 3 日 1 1 INPUTOUTPUT 1 InputOutput 题目描述 用 cin 输入你的姓名 ( 没有空格 ) 和年龄 ( 整数 ), 并用 cout 输出 输入输出符合以下范例 输入 master 999 输出 I am master, 999 years old. 注意 "," 后面有一个空格,"." 结束,

More information

Microsoft Word - 01.DOC

Microsoft Word - 01.DOC 第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的

More information

Guava学习之Resources

Guava学习之Resources Resources 提供提供操作 classpath 路径下所有资源的方法 除非另有说明, 否则类中所有方法的参数都不能为 null 虽然有些方法的参数是 URL 类型的, 但是这些方法实现通常不是以 HTTP 完成的 ; 同时这些资源也非 classpath 路径下的 下面两个函数都是根据资源的名称得到其绝对路径, 从函数里面可以看出,Resources 类中的 getresource 函数都是基于

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

chap07.key

chap07.key #include void two(); void three(); int main() printf("i'm in main.\n"); two(); return 0; void two() printf("i'm in two.\n"); three(); void three() printf("i'm in three.\n"); void, int 标识符逗号分隔,

More information

Microsoft Word - 新1-12.doc

Microsoft Word - 新1-12.doc 实训 5 面向对象编程练习 实训 5 面向对象编程练习 5.1 实训目的 通过编程和上机实验理解 Java 语言是如何体现面向对象编程基本思想 以及如何创建类 和对象 了解成员变量和成员方法的特性 5.2 实训要求 编写一个体现面向对象思想的程序 编写一个创建对象和使用对象的方法的程序 5.3 实训内容 5.3.1 创建对象并使用对象 1 定义一个 Person 类 可以在应用程序中使用该类 成员属性

More information

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例 帝国 CMS 下在 PHP 文件中调用数据库类执行 SQL 语句实例 这篇文章主要介绍了帝国 CMS 下在 PHP 文件中调用数据库类执行 SQL 语句实例, 本文还详细介绍了帝国 CMS 数据库类中的一些常用方法, 需要的朋友可以参考下 例 1: 连接 MYSQL 数据库例子 (a.php)

More information

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

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-065Big5 Title : Sun Certified Programmer for the Java 2 Platform, SE 6.0 Version : Demo 1 / 14 1. 35. String #name = "Jane Doe"; 36. int

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 3 章 lambda 表达式及其应用 lambda 表达式是 Java 8 提供的一种新特性, 它使得 Java 也能像 C# 和 C++ 语言一样进行简单的 函数式编程, 这不仅简化了某些通用结构的实现方式, 也大大增强了 Java 语言的表达功能 3.1 lambda 表达式简介 lambda 表达式是基于数学中的 λ 演算得名, 本质上就是一个没有方法名的匿名方法 例如, 有一个方法定义如下

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款 JAVA 程 序 设 计 ( 肆 ) 徐 东 / 数 学 系 使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款 使 用 Java class 代 表 保 险 箱 public class SaveBox 类 名 类 类 体 实 现 封 装 性 使 用 class SaveBox 代 表 保

More information

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx 运算符重载 Operator Overloading class Point { public: ; double x_, y_; Why Operator Overloading? Point (double x =0, double y = 0):x_(x),y_(y) { int main(){ Point a(1., 2), b(3,4); Point c = a + b; return 0;

More information

OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点

OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public

More information

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, http://debut.cis.nctu.edu.tw/~chi Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, : POSITIVE_INFINITY NEGATIVE_INFINITY

More information

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

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入 100 年 特 種 考 試 地 方 政 府 公 務 人 員 考 試 試 題 等 別 : 三 等 考 試 類 科 : 資 訊 處 理 科 目 : 系 統 分 析 與 設 計 一 請 參 考 下 列 旅 館 管 理 系 統 的 使 用 案 例 圖 (Use Case Diagram) 撰 寫 預 約 房 間 的 使 用 案 例 規 格 書 (Use Case Specification), 繪 出 入

More information

Microsoft Word - 第5章.doc

Microsoft Word - 第5章.doc 第 5 章 面向对象编程 除了基本的类和对象,Java 语言的面向对象编程还包括抽象类 接口 内部类及包等高级特性 通过对这些高级特性的支持,Java 语言全面实现了面向对象的编程 本章将进一步深入介绍 Java 语言面向对象编程方面的知识 5.1 类的三大特性 第 4 章介绍了有关类定义的基本知识 面向对象中的类还具有封装 继承与多态的特性, 这也是面向对象编程所具有的重要特点 Java 语言对类的封装

More information

教案模板4-2

教案模板4-2 传智播客 Java 基础入门 教学设计 课程名称 : Java 基础入门 授课年级 : 2014 年级 授课学期 : 2014 学年第一学期 教师姓名 : 某某老师 2014 年 02 月 09 日 课题名称第 3 章面向对象上 计划学时 6 课时 Java 是一种面向对象的语言, 认识面向对象的编程思想对于 Java 学习至关重 内容分析 要 在面向对象中, 有两个重要的概念, 分别是类和对象,

More information

拦截器(Interceptor)的学习

拦截器(Interceptor)的学习 二 拦截器 (Interceptor) 的学习 拦截器可以监听程序的一个或所有方法 拦截器对方法调用流提供了细粒度控制 可以在无状态会话 bean 有状态会话 bean 和消息驱动 bean 上使用它们 拦截器可以是同一 bean 类中的方法或是一个外部类 下面介绍如何在 Session Bean 类中使用外部拦截器类 @Interceptors 注释指定一个或多个在外部类中定义的拦截器 下面拦截器

More information

Microsoft Word - word模板-教师.doc

Microsoft Word - word模板-教师.doc 传智播客 Java 基础入门 教学设计 课程名称 : Java 基础入门 授课年级 : 2014 年级 授课学期 : 2014 学年第一学期 教师姓名 : 某某老师 2014 年 02 月 09 日 课题名称内容分析教学目标及基本要求重点及措施难点及措施 计划第 3 章面向对象上 6 课时学时 Java 是一种面向对象的语言, 认识面向对象的编程思想对于 Java 学习至关重要 在面向对象中, 有两个重要的概念,

More information

OOP with Java 通知 : Project 2 提交时间 : 3 月 15 日晚 9 点

OOP with Java 通知 : Project 2 提交时间 : 3 月 15 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 : Project 2 提交时间 : 3 月 15 日晚 9 点 复习 : Java 类型 基本类型 boolean, char, 封装 (wrappers) 类 (class) 定义 class MyType { int i; double d; 数据 (Fields) char c; void set(double

More information

OOP with Java 通知 : Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢

OOP with Java 通知 : Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 : Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 Email: 51141201063@ecnu.cn 复习 : Java 类型 基本类型 boolean, char, 封装 (wrappers) 类 (class) 定义 class MyType { int i;

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 The BitCoin Scripting Language 交易实例 交易结构 "result": { "txid": "921a dd24", "hash": "921a dd24", "version": 1, "size": 226, "locktime": 0, "vin": [ ], "vout": [ ], "blockhash": "0000000000000000002c510d

More information

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

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public char

More information

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

OOP with Java 通知 Project 3: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3: 4 月 19 日晚 9 点 复习 Upcasting 同一基类的不同子类可以被视为同一类型 ( 基类 ) 放宽类型一致性 简化接口 class A{ class B{ A a = new A(); B b = new B(); // A a = new B(); compile

More information

chp5_1

chp5_1 Java 软件设计基础 5. 继承与多态 类的封装 类的特性 Java 程序设计的基本单位是类, 类是用来创建具体对象的模板, 有以下三个重要特性 : 封装 Java 语言中, 对象就是对一组变量和相关方法的封装 (Encapsulation), 通过对对象的封装, 实现模块化和信息隐藏 通过对类的成员辅以一定的访问限制, 实现类中成员的信息隐藏 继承 继承 (inheritance) 允许创建分等级层次的类,

More information

EJB-Programming-4-cn.doc

EJB-Programming-4-cn.doc EJB (4) : (Entity Bean Value Object ) JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Session Bean J2EE Session Façade Design Pattern Session Bean Session

More information

javaexample-02.pdf

javaexample-02.pdf n e w. s t a t i c s t a t i c 3 1 3 2 p u b l i c p r i v a t e p r o t e c t e d j a v a. l a n g. O b j e c t O b j e c t Rect R e c t x 1 y 1 x 2 y 2 R e c t t o S t r i n g ( ) j a v a. l a n g. O

More information

第3 章 类 对象与方法 3.1 类 类的定义 在 Objective-C 中 每个类的定义包括两个部分 接口 interface 和实现 implementation 接口部 分定义在.h 文件中 包含类的声明 属性以及方法 主要作用是对外提供访问接口 实现部分定义在.m 文件中 主要

第3 章 类 对象与方法 3.1 类 类的定义 在 Objective-C 中 每个类的定义包括两个部分 接口 interface 和实现 implementation 接口部 分定义在.h 文件中 包含类的声明 属性以及方法 主要作用是对外提供访问接口 实现部分定义在.m 文件中 主要 第3 章 类 对象与方法 3.1 类 3.1.1 类的定义 在 Objective-C 中 每个类的定义包括两个部分 接口 interface 和实现 implementation 接口部 分定义在.h 文件中 包含类的声明 属性以及方法 主要作用是对外提供访问接口 实现部分定义在.m 文件中 主要用于方法的功能实现 这种定义类的方法 好处在于将公共声明 接口 与代码实现分开 对外屏蔽了功能实现的细节

More information

《计算概论》课程 第十九讲 C 程序设计语言应用

《计算概论》课程 第十九讲  C 程序设计语言应用 Java 高级技术 课程第二讲 Java 语言的面向对象特性 (2) 李戈 北京大学信息科学技术学院软件研究所 2010 年 3 月 21 日 课程助教 : 前言 黎育龙 (10817195@pub.ss.pku.edu.cn) Email 标题 :Java 高级技术 + 题目 请不要把作业发到我的信箱 ; 新的课程网站 http://www.ontoedu.pku.edu.cn/index.jsp

More information

Microsoft PowerPoint - 07 派生数据类型

Microsoft PowerPoint - 07 派生数据类型 能源与动力工程学院 目录 派生类型 陈 斌 固有数据类型 数值型 (numerical) 整型 INTEGER 实型 REAL 复数型 COMPLEX 非数值型 字符型 CHARACTER 逻辑型 ( 布尔型 )LOGICAL 自定义数据类型 ( 派生类型, derived type) 派生类型是指用户利用 Fortran 系统内部类型, 如整型 实型 复数型 逻辑型 字符型等的组合自行创建出一个新的数据类型,

More information

《大话设计模式》第一章

《大话设计模式》第一章 第 1 章 代 码 无 错 就 是 优? 简 单 工 厂 模 式 1.1 面 试 受 挫 小 菜 今 年 计 算 机 专 业 大 四 了, 学 了 不 少 软 件 开 发 方 面 的 东 西, 也 学 着 编 了 些 小 程 序, 踌 躇 满 志, 一 心 要 找 一 个 好 单 位 当 投 递 了 无 数 份 简 历 后, 终 于 收 到 了 一 个 单 位 的 面 试 通 知, 小 菜 欣 喜

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,

More information

Mac Java import com.apple.mrj.*;... public class MyFirstApp extends JFrame implements ActionListener, MRJAboutHandler, MRJQuitHandler {... public MyFirstApp() {... MRJApplicationUtils.registerAboutHandler(this);

More information

Struts2自定义类型转换.doc

Struts2自定义类型转换.doc Struts2 自定义类型转换 原理 struts2 的自定义类型转换机制为复杂类型的输入输出处理提供了便捷.struts2 已经为我们提供了几乎所有的 primitive 类型以及常用类型 ( 如 Date) 的类型转换器, 我们也可以为我们自定义类添加自定义类型转化器. struts2 为我们提供了一个类型转化器的入口 : ognl.defaulttypeconverter, 或继承 org.apache.struts2.util.strutstypeconverter,

More information

untitled

untitled 1 Outline 類别 欄 (1) 類 類 狀 更 易 類 理 若 類 利 來 利 using 來 namespace 類 ; (2) namespace IBM class Notebook namespace Compaq class Notebook 類别 類 來 類 列 欄 (field) (property) (method) (event) 類 例 立 來 車 類 類 立 車 欄 料

More information

public class Phone { String brand; double price; void call(){ System.out.println("hi,how are you doing"); 案例 3-2 对象的创建及对象内存图 1 考核知识点对象的创建和引用 掌握创建对象的方式

public class Phone { String brand; double price; void call(){ System.out.println(hi,how are you doing); 案例 3-2 对象的创建及对象内存图 1 考核知识点对象的创建和引用 掌握创建对象的方式 第三章补充案例 案例 3-1 类的定义 1 考核知识点类的定义 掌握类定义的格式 掌握如何在类中定义成员变量和成员方法 3 需求分析在程序中, 设计一个表示学生的类, 该类具有以下属性和方法 : 该类具有表示姓名的属性 name 该类具有表示年龄的属性 age 该类具有表示说话行为的方法 speak, 并且用于输出学生的姓名和年龄 1) 使用 class 关键字定义一个表示学生类型的类, 类名为 Student

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

2. AOP 底层技术实现 小风 Java 实战系列教程 关键词 : 代理模式 代理模型分为两种 : 1) 接口代理 (JDK 动态代理 ) 2) 子类代理 (Cglib 子类代理 ) 需求 :CustomerService 业务类, 有 save,update 方法, 希望在 save,updat

2. AOP 底层技术实现 小风 Java 实战系列教程 关键词 : 代理模式 代理模型分为两种 : 1) 接口代理 (JDK 动态代理 ) 2) 子类代理 (Cglib 子类代理 ) 需求 :CustomerService 业务类, 有 save,update 方法, 希望在 save,updat 本章学习目标 小风 Java 实战系列教程 AOP 思想概述 AOP 底层技术实现 AOP 术语介绍 SpringAOP 的 XML 方式 HelloWorld SpringAOP 的 XML 方式配置细节 SpringAOP 的注解方式 SpringAOP 的零配置方式 1. AOP 思想概述 1.1. AOP 思想简介 1.2. AOP 的作用 2. AOP 底层技术实现 小风 Java 实战系列教程

More information

内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌

内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌 语 言 程 序 设 计 郑 莉 胡 家 威 编 著 清 华 大 学 逸 夫 图 书 馆 北 京 内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌 握 语

More information

姓名 : 年级专业 : 学号 : 凡年级专业 姓名 学号错写 漏写或字迹不清者, 成绩按零分记 密 封 线 java 较难 试卷 总分 题号 一 二 三 四 五 题分 得分 D 国际通信协议 4 下面选项中, 不是面向对象的特征的是 ( ) A 封装 B 继承 得分 一 单选题 ( 每题 3 分,

姓名 : 年级专业 : 学号 : 凡年级专业 姓名 学号错写 漏写或字迹不清者, 成绩按零分记 密 封 线 java 较难 试卷 总分 题号 一 二 三 四 五 题分 得分 D 国际通信协议 4 下面选项中, 不是面向对象的特征的是 ( ) A 封装 B 继承 得分 一 单选题 ( 每题 3 分, java 较难 试卷 总分 题号 一 二 三 四 五 题分 D 国际通信协议 4 下面选项中, 不是面向对象的特征的是 ( ) A 封装 B 继承 一 单选题 ( 每题 3 分, 共计 15 分 ) 1 下列修饰符中, 成员内部类被 ( ) 修饰后, 可以被外界访问 C 多态 D 重构 5 下列关于构造方法重载的说法中, 错误的是 () A 不同构造方法中调用本类其它的构造方法时, 需要使用 this([

More information

Microsoft PowerPoint - 08_OO_CJC.ppt

Microsoft PowerPoint - 08_OO_CJC.ppt C++ 中的 Hello World! C 程序设计语言 第 8 章 OO 与 C++ Java C# 孙志岗 sun@hit.edu.cn http://sunner.cn 兼容 C 语言的 : #include int main() printf("hello,, world!\n"); return 0; 更具 C++ 味道的 : #include int

More information

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

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit Tomcat Web JUnit Cactus JUnit Java Cactus JUnit 26.1 JUnit Java JUnit JUnit Java JSP Servlet JUnit Java Erich Gamma Kent Beck xunit JUnit boolean JUnit Java JUnit Java JUnit Java 26.1.1 JUnit JUnit How

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Fortran Algol Pascal Modula-2 BCPL C Simula SmallTalk C++ Ada Java C# C Fortran 5.1 message A B 5.2 1 class Vehicle subclass Car object mycar public class Vehicle extends Object{ public int WheelNum

More information

Guava学习之CharSequenceReader

Guava学习之CharSequenceReader CharSequenceReader 类是以 CharSequence 的形式读取字符 CharSequenceReader 类继承自 Reader 类, 除了 remaining() hasremaining() 以及 checkopen() 函数之后, 其他的函数都是重写 Reader 类中的函数 CharSequenceReader 类声明没有用 public 关键字, 所以我们暂时还不能调用这个类

More information

Microsoft Word - JCS5.doc

Microsoft Word - JCS5.doc 第 5 章进一步讨论对象和类 5.1 抽象数据类型 5.1.1 概述 绝大多数程序设计语言都预定义了一些基本数据类型, 并相应定义了对那些类型的实例执行的操作 比如, 对整型 实型等数值类型, 有加 减 乘 除等操作 ; 对逻辑类型, 有逻辑与 逻辑或 逻辑非等操作 对于用户自定义的复合数据类型, 需要由程序员自己定义一些方法, 对该类型的实例进行所需的操作 在早期许多程序设计语言中, 复合数据类型及其相关操作的代码之间没有特殊的联系

More information

untitled

untitled 1 Outline 料 類 說 Tang, Shih-Hsuan 2006/07/26 ~ 2006/09/02 六 PM 7:00 ~ 9:30 聯 ives.net@gmail.com www.csie.ntu.edu.tw/~r93057/aspnet134 度 C# 力 度 C# Web SQL 料 DataGrid DataList 參 ASP.NET 1.0 C# 例 ASP.NET 立

More information

JavaIO.PDF

JavaIO.PDF O u t p u t S t ream j a v a. i o. O u t p u t S t r e a m w r i t e () f l u s h () c l o s e () public abstract void write(int b) throws IOException public void write(byte[] data) throws IOException

More information

使用MapReduce读取XML文件

使用MapReduce读取XML文件 使用 MapReduce 读取 XML 文件 XML( 可扩展标记语言, 英语 :extensible Markup Language, 简称 : XML) 是一种标记语言, 也是行业标准数据交换交换格式, 它很适合在系统之间进行数据存储和交换 ( 话说 Hadoop H ive 等的配置文件就是 XML 格式的 ) 本文将介绍如何使用 MapReduce 来读取 XML 文件 但是 Had oop

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc Java C++ Pascal C# C# if if if for while do while foreach while do while C# 3.1.1 ; 3-1 ischeck Test() While ischeck while static bool ischeck = true; public static void Test() while (ischeck) ; ischeck

More information

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

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-055Big5 Title : Sun Certified Programmer for the Java 2 Platform.SE 5.0 Version : Demo 1 / 22 1. 11. public static void parse(string str)

More information

ExcelUtility 类库使用说明 ( 续 ) 开发 / 设计 : 左文俊 第一个新增功能, 列宽自适应, 当超过 30 个字符则将单元格内容设为换行 任意一个无模板的导出方法均支持该功能, 示例代码如下 : /// <summary> /// 测试方法

ExcelUtility 类库使用说明 ( 续 ) 开发 / 设计 : 左文俊 第一个新增功能, 列宽自适应, 当超过 30 个字符则将单元格内容设为换行 任意一个无模板的导出方法均支持该功能, 示例代码如下 : /// <summary> /// 测试方法 ExcelUtility 类库使用说明 ( 续 ) 开发 / 设计 : 左文俊 第一个新增功能, 列宽自适应, 当超过 0 个字符则将单元格内容设为换行 任意一个无模板的导出方法均支持该功能, 示例代码如下 : 0 /// 测试方法 : 测试将 DataTable 导出到 EXCEL, 无模板 public void TestExportToExcelByDataTable() string excelpath

More information

Java Access 5-1 Server Client Client Server Server Client 5-2 DataInputStream Class java.io.datainptstream (extends) FilterInputStream InputStream Obj

Java Access 5-1 Server Client Client Server Server Client 5-2 DataInputStream Class java.io.datainptstream (extends) FilterInputStream InputStream Obj Message Transition 5-1 5-2 DataInputStream Class 5-3 DataOutputStream Class 5-4 PrintStream Class 5-5 (Message Transition) (Exercises) Java Access 5-1 Server Client Client Server Server Client 5-2 DataInputStream

More information

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复 获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复 获取将导致上次获取的 access_token 失效 接入方可以使用 AppID 和 AppSecret

More information

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

res/layout 目录下的 main.xml 源码 : <?xml version=1.0 encoding=utf 8?> <TabHost android:layout_height=fill_parent xml 拓展训练 1- 界面布局 1. 界面布局的重要性做应用程序, 界面是最基本的 Andorid 的界面, 需要写在 res/layout 的 xml 里面, 一般情况下一个 xml 对应一个界面 Android 界面布局有点像写 html( 连注释代码的方式都一样 ), 要先给 Android 定框架, 然后再在框架里面放控件,Android 提供了几种框架,AbsoluteLayout,LinearLayout,

More information

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

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public char

More information

CHAPTER VC#

CHAPTER VC# 1. 2. 3. 4. CHAPTER 2-1 2-2 2-3 2-4 VC# 2-5 2-6 2-7 2-8 Visual C# 2008 2-1 Visual C# 0~100 (-32768~+32767) 2 4 VC# (Overflow) 2-1 2-2 2-1 2-1.1 2-1 1 10 10!(1 10) 2-3 Visual C# 2008 10! 32767 short( )

More information

3.1 num = 3 ch = 'C' 2

3.1 num = 3 ch = 'C' 2 Java 1 3.1 num = 3 ch = 'C' 2 final 3.1 final : final final double PI=3.1415926; 3 3.2 4 int 3.2 (long int) (int) (short int) (byte) short sum; // sum 5 3.2 Java int long num=32967359818l; C:\java\app3_2.java:6:

More information

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式]

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式] 用户定义类型 User-defined Datatypes classes and structs 几何向量 (Geometry Vector) 二维平面上的向量由起点和终点构成 每个点包含两个坐标 (x, y), 因此一个向量需要四个实数表示 Start= (0.9,1.5) Start= (0.4,0.8) int main() { double xstart = 0.4; double xend

More information

设计模式 Design Patterns

设计模式 Design Patterns 丁勇 Email:18442056@QQ.com 组件技术概述 现在软件开发都已经转向了基于组件的开发, 目前具备代表性的组件技术有微软的 COM COM+, 有 Sun 的 Bean 和 EJB(Enterprise Bean), 另外还有 CORBA(Common Object Request Broker Architecture, 公 共对象请求代理结构 ) Bean Bean 规范将 软件组件

More information

chp4

chp4 Java 软件开发基础 4. 面向对象的程序设计基础 4.1 面向对象基础 对象 现实世界中复杂的对象是由许多小的 简单的对象组成的 客观存在的物体就是最基本的对象 不同的物体有共性, 共性存在于个性之中, 物体的个性又继承了共性 对象的状态属性 对象蕴含着许多信息, 可以用一组状态来表征 对象的行为操作 对象内部含有对数据的操作, 即对象的行为操作 某类事物的抽象 某类对象是对现实世界具有共同特性的某类事物的抽象

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Java application Java main applet Web applet Runnable Thread CPU Thread 1 Thread 2 Thread 3 CUP Thread 1 Thread 2 Thread 3 ,,. (new) Thread (runnable) start( ) CPU (running) run ( ) blocked CPU sleep(

More information

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 本章学习目标 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 配置视图解析器 @RequestMapping 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 和 Struts2 都属于表现层的框架, 它是 Spring 框架的一部分, 我们可 以从 Spring 的整体结构中看得出来 :

More information

JAVA 单元 2.1 四则运算机 ( 一 ) 单元教学进度设计 教学环节 教学内容 教师学生活动活动 反馈 反馈课前作业完成情况 反馈加分 1. 下面哪些是合法的变量名? ( ) A.2variable 答案 :DEG B..variable2 解答 : C.._whatavariable A:/

JAVA 单元 2.1 四则运算机 ( 一 ) 单元教学进度设计 教学环节 教学内容 教师学生活动活动 反馈 反馈课前作业完成情况 反馈加分 1. 下面哪些是合法的变量名? ( ) A.2variable 答案 :DEG B..variable2 解答 : C.._whatavariable A:/ 单元 2.1 四则运算机 ( 一 ) 单元教学进度设计 教学环节 教学内容 教师学生活动活动 反馈 反馈课前作业完成情况 反馈加分 1. 下面哪些是合法的变量名? ( ) A.2variable 答案 :DEG B..variable2 解答 : C.._whatavariable A:// 不能以数字开头 D._3_ B:// 不能用点和空格 提问 抢答 E.$anothervar C: // 不能用点和空格

More information

1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET NET Framework.NET Framework 2.0 ( 3 ).NET Framework 2.0.NET F

1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET NET Framework.NET Framework 2.0 ( 3 ).NET Framework 2.0.NET F 1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET 2.0 2.0.NET Framework.NET Framework 2.0 ( 3).NET Framework 2.0.NET Framework ( System ) o o o o o o Boxing UnBoxing() o

More information

chp6.ppt

chp6.ppt Java 软 件 设 计 基 础 6. 异 常 处 理 编 程 时 会 遇 到 如 下 三 种 错 误 : 语 法 错 误 (syntax error) 没 有 遵 循 语 言 的 规 则, 出 现 语 法 格 式 上 的 错 误, 可 被 编 译 器 发 现 并 易 于 纠 正 ; 逻 辑 错 误 (logic error) 即 我 们 常 说 的 bug, 意 指 编 写 的 代 码 在 执 行

More information

C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ2 - 参考答案 MASTER 2019 年 5 月 3 日 1 1 TEMPLATE 1 Template 描述 使用模板函数求最大值 使用如下 main 函数对程序进行测试 int main() { double a, b; cin >> a >> b; cout c >> d; cout

More information

第三章面向对象基本特性 面向对象程序设计是一种先进的编程思想, 更加容易解决复杂的问题 面向对象系统最突出的特性是封装性 继承性和多态性 学习完本章节, 您能够 : 理解封装的概念 实现对象封装特性 实现继承特性 使用接口 掌握对象的多态性 任务 3.1 保护个人数据 情境描述 Tom

第三章面向对象基本特性 面向对象程序设计是一种先进的编程思想, 更加容易解决复杂的问题 面向对象系统最突出的特性是封装性 继承性和多态性 学习完本章节, 您能够 : 理解封装的概念 实现对象封装特性 实现继承特性 使用接口 掌握对象的多态性 任务 3.1 保护个人数据 情境描述 Tom 第三章面向对象基本特性 面向对象程序设计是一种先进的编程思想, 更加容易解决复杂的问题 面向对象系统最突出的特性是封装性 继承性和多态性 学习完本章节, 您能够 : 理解封装的概念 实现对象封装特性 实现继承特性 使用接口 掌握对象的多态性 任务 3.1 保护个人数据 3.1.1 情境描述 Tom 设计的 A 类员工类, 外部可以直接访问它的成员变量, 在现实社会中, 一个对象的 某些属性外界是不可以得知的,

More information

01_Service

01_Service 移动平台应用软件开发 Service 主讲 : 张齐勋 zhangqx@ss.pku.edu.cn 移动平台应用软件开发 课程建设小组 北京大学 二零一七年 什么是 Service 与 Activity 一样, 同属 Android 基本组件 后台运行, 不与用户交互, 没有可视化界面 最常见的 Service 如 : 在后台播放歌曲 后台执行文件的下载 同样需在 AndroidManifest.xml

More information

Spring3.x开发入门

Spring3.x开发入门 Spring Bean 管理 Spring 的工厂类 课程安排 Spring 的 Bean 管理 (XML 方式 ) Spring 的属性注入 (XML 方式 ) Spring 的 Bean 管理 ( 注解方式 ) Spring 的属性注入 ( 注解方式 ) Spring 的工厂类 Spring 的 Bean 管理 (XML 方式 ) 三种实例化 Bean 的方式 使用类构造器实例化 ( 默认无参数

More information

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6: Chapter 15. Suppressed Exception CH14 Finally Block Java SE 7 try-with-resources JVM cleanup try-with-resources JVM cleanup cleanup Java SE 7 Throwable getsuppressed Throwable[] getsuppressed() Suppressed

More information

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple halcon 与 C# 混合编程之 Halcon 代码调用 写在前面 完成 halcon 与 C# 混合编程的环境配置后, 进行界面布局设计构思每一个按钮所需要实现 的功能, 将 Halcon 导出的代码复制至相应的 C# 模块下即可 halcon 源程序 : dev_open_window(0, 0, 512, 512, 'black', WindowHandle) read_image (Image,

More information

OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac)

OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac) OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac) 复习 面向对象编程 将实际问题分解成不同的对象 不的对象提供不同的服务 对象之间可以传递消息 例子小李深夜

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

untitled

untitled How to using M-Power Report API M-Power Report API 力 了 M-Power Report -- Java (Library) M-Power Report API 行 Java M-Power Report M-Power Report API ( 30 ) PDF/HTML/CSV/XLS JPEG/PNG/SVG 料 料 OutputStream

More information

Microsoft Word - ch04三校.doc

Microsoft Word - ch04三校.doc 4-1 4-1-1 (Object) (State) (Behavior) ( ) ( ) ( method) ( properties) ( functions) 4-2 4-1-2 (Message) ( ) ( ) ( ) A B A ( ) ( ) ( YourCar) ( changegear) ( lowergear) 4-1-3 (Class) (Blueprint) 4-3 changegear

More information

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 -> 目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController

More information

运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2

运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2 第十一讲 运算符重载 与类型转换 运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2 为什么要运算符重载 预定义的运算符只针对基本数据类型, 若要对类的对象进行类似的运算, 需要重新定义运算符的功能 运算符重载实质就是函数重载 : 对已有的运算符赋予多重含义, 使得同一个运算符作用于不同类型的数据时导致不同的行为

More information

2009年3月全国计算机等级考试二级Java语言程序设计笔试试题

2009年3月全国计算机等级考试二级Java语言程序设计笔试试题 2009 年 3 月 全 国 计 算 机 等 级 考 试 笔 试 试 卷 二 级 Java 语 言 程 序 设 计 ( 考 试 时 间 90 分 钟, 满 分 100 分 ) 一 选 择 题 ( 每 题 2 分, 共 70 分 ) 下 列 各 题 A) B) C) D) 四 个 选 项 中, 只 有 一 个 选 项 是 正 确 的 请 将 正 确 选 项 填 涂 在 答 题 卡 相 应 位 置 上,

More information

Microsoft Word - 第2章.doc

Microsoft Word - 第2章.doc 2 第第 2 章 学习第 1 章后, 读者已经对 Java 语言有了初步的了解, 本章将具体解析 Java 类的组成元素 任何一个 Java 类, 都有 5 种基本组成元素 : 属性 方法 构造方法 块和内部类 其中属性 方法 构造方法是使用最多的元素, 而块 内部类使用较少 本章将对各种元素进行学习 Java 类基本结构 2.1 类 类 Java 类的声明形式 访问权限修饰符 修饰符 class

More information

9, : Java 19., [4 ]. 3 Apla2Java Apla PAR,Apla2Java Apla Java.,Apla,,, 1. 1 Apla Apla A[J ] Get elem (set A) A J A B Intersection(set A,set B) A B A B

9, : Java 19., [4 ]. 3 Apla2Java Apla PAR,Apla2Java Apla Java.,Apla,,, 1. 1 Apla Apla A[J ] Get elem (set A) A J A B Intersection(set A,set B) A B A B 25 9 2008 9 M ICROEL ECTRON ICS & COMPU TER Vol. 25 No. 9 September 2008 J ava 1,2, 1,2, 1,2 (1, 330022 ; 2, 330022) :,. Apla - Java,,.. : PAR ;Apla - Java ; ;CMP ; : TP311 : A : 1000-7180 (2008) 09-0018

More information

Learning Java

Learning Java Java Introduction to Java Programming (Third Edition) Prentice-Hall,Inc. Y.Daniel Liang 2001 Java 2002.2 Java2 2001.10 Java2 Philip Heller & Simon Roberts 1999.4 Java2 2001.3 Java2 21 2002.4 Java UML 2002.10

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 友乾营 报表的 SQL 植入风险 规避风险 : 让你的报表变的安全起来 SQL 植入的概念 恶意的 SQL 归根结底 : 执行了不该允许执行的 SQL 命令, 达到非法的目的 常见案例 骗过登录验证非法获取账号信息篡改 删除数据 为什么存在 SQL 植入 植入原理 如何攻击 特殊的输入参数 未处理特殊字符 -- # 数据库配置不合理 植入原理 : 案例 1, 特殊输入参数 union or 猜表名

More information

Microsoft Word - 正文.doc

Microsoft Word - 正文.doc 第 2 章 Java 语言基础 通过本章的实践, 要掌握 Java 中的标识符 关键字 常量, 熟练掌握算术 关 系 逻辑 条件 赋值 位运算符的使用, 掌握简单顺序结构的程序设计 2.1 典型习题解答 2.1 Java 中怎样进行注释? 解答 Java 语言中的注释有 3 种形式 : (1) 单行 : // (2) 多行 : /* */ (3) 文档注释 : /** */ 第三种形式是第二种形式的变形,

More information

前言 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

前言 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 前言 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 C# 7 More Effective C# C# C# C# C# C# Common Language Runtime CLR just-in-time

More information

Microsoft PowerPoint - 04-Inheritance.ppt

Microsoft PowerPoint - 04-Inheritance.ppt 继承 派生与多态性 1 本章主要内容 类的继承与派生 类成员的访问控制 简单继承与多重继承 派生类的构造 析构函数 多态性 2 1 类的继承与派生 保持已有类的特性, 并在其基础上产生新的类, 称新类继承了已有类的特征, 或称已有类派生出新类 被继承的已有类称为基类 ( 或父类 ) 派生出的新类称为派生类 派生类将自动继承基类的所有特性 ( 属性和方法 ) 派生类可以定义新的特性 ( 属性和方法 )

More information