strmysql concat函数怎样编主函数在c++中实现

MySQL数据库中函数CONCAT与GROUP_CONCAT对比分析(一)
】 浏览:43次
MySQL中函数CONCAT与GROUP_CONCAT对比分析。
一、CONCAT()函数
CONCAT()函数用于将多个字符串连接成一个字符串。
使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为
+----+--------+
| id | name|
+----+--------+
|1 | BioCyc |
+----+--------+
1、语法及使用特点:
CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。可以有一个或多个参数。
2、使用示例:
SELECT CONCAT(id, ‘,’, name) AS con FROM info LIMIT 1;返回结果为
+----------+
+----------+
| 1,BioCyc |
+----------+
SELECT CONCAT(‘My’, NULL, ‘QL’);返回结果为
+--------------------------+
| CONCAT('My', NULL, 'QL') |
+--------------------------+
+--------------------------+
3、如何指定参数之间的分隔符
使用函数CONCAT_WS()。使用语法为:CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。但是CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。
如SELECT CONCAT_WS('_',id,name) AS con_ws FROM info LIMIT 1;返回结果为
+----------+
+----------+
| 1_BioCyc |
+----------+
SELECT CONCAT_WS(',','First name',NULL,'Last Name');返回结果为
+----------------------------------------------+
| CONCAT_WS(',','First name',NULL,'Last Name') |
+----------------------------------------------+
| First name,Last Name|
+----------------------------------------------+
二、GROUP_CONCAT()函数
GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。
使用表info作为示例,其中语句SELECT locus,id,journal FROM info WHERE locus IN('AB086827','AF040764');的返回结果为
+----------+----+--------------------------+
| locus| id | journal|
+----------+----+--------------------------+
| AB | Unpublished|
| AB | Submitted (20-JUN-2002)|
| AF040764 | 23 | Unpublished|
| AF040764 | 24 | Submitted (31-DEC-1997)|
+----------+----+--------------------------+
1、使用语法及特点:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]]
[SEPARATOR str_val])
在 MySQL 中,你可以得到表达式结合体的连结值。通过使用 DISTINCT 可以排除重复值。如果希望对结果中的值进行排序,可以使用 ORDER BY 子句。
SEPARATOR 是一个字符串值,它被用于插入到结果值中。缺省为一个逗号 (&,&),可以通过指定 SEPARATOR && 完全地移除这个分隔符。
可以通过变量 group_concat_max_len 设置一个最大的长度。在运行时执行的句法如下: SET [SESSION | GLOBAL] group_concat_max_len = unsigned_
如果最大长度被设置,结果值被剪切到这个最大长度。如果分组的字符过长,可以对参数进行设置:SET @@global.group_concat_max_len=40000;
2、使用示例:
语句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY 的返回结果为
+----------+------------------+
| locus| GROUP_CONCAT(id) |
+----------+------------------+
| AB086827 | 1,2|
| AF040764 | 23,24|
+----------+------------------+
语句 SELECT locus,GROUP_CONCAT(distinct id ORDER BY idDESC SEPARATOR '_') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY的返回结果为
+----------+----------------------------------------------------------+
| locus| GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR'_')|
+----------+----------------------------------------------------------+
| AB086827 | 2_1|
| AF040764 | 24_23|
+----------+----------------------------------------------------------+
语句SELECT locus,GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY的返回结果为
+----------+------------------------------------------------------
【】【】【】
【】【】【】
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_74
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_70
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_68
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_97
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_99
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_00
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_70
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_61
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_75
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_35
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3当前位置: >>
java程序设计 课件 第3章
第3章类与对象第3章 类与对象3.1 面向对象的基本思想和基本概念3.2 案例 3.3 类的声明与对象的创建 3.4 继承 3.5 包的使用3.6 编程实例实训三 面向对象程序设计 习题三 第3章类与对象3.1 面向对象的基本思想和基本概念大部分传统的高级程序设计语言(如C语言)都是过 程化的语言,在软件开发的过程中采用自顶向下逐步 细化的方法将整个程序描述为一个过程。对于小型的 系统,这种方法是可行的,但是当系统规模很大,复 杂度很高时,用过程化方法描述变得十分困难,面向 对象的软件开发方法可以很好地解决这个问题。 第3章类与对象目前,面向对象的方法在软件开发工作中得到了 广泛的应用,越来越多的软件开发工具开始支持面向对象的开发方法。Java语言就是一种面向对象的程序设计语言,要充分利用Java语言的特性首先应该理解 面向对象的基本思想。 第3章类与对象3.1.1 面向对象的基本思想面向对象的基本思想认为系统是由若干个对象构 成的,每个对象都有各自的内部状态和运动规律,不 同对象之间通过消息传送相互作用和联系。 采用对象的观点看待所要解决的问题,并将其抽象为系统是极其自然与简单的,因为它符合人类的思维习惯,使得应用系统更容易理解。同时,由于应用 系统是由相互独立的对象构成的,使得系统的修改可以局部化,因此系统更易于维护。 第3章类与对象例如,对于一个企业的管理信息系统,将整个系统描述成一个过程是难以想像的,但可以分别描述各 个部门的特性及工作流程,然后描述部门之间的联系。 这里各个部门就是组成企业的对象,当然,在描述每 个部门特性时可以采用同样的方法。 第3章类与对象3.1.2 对象与类对象是面向对象方法中的一个重要概念。所谓对 象,是指客观世界中事物在计算机领域中的抽象,用 一组数据和施加于该组数据上的一组操作(行为)来描述。 对象的描述通常由三个部分组成: (1) 私有的数据结构。用于描述对象的内部状态。 (2) 处理,称为操作或方法。它是施加于数据结构 之上的。 (3) 接口。这是对象可被共享的部分,消息通过接 口调用相应的操作。接口规定哪些操作是允许的,它 不提供操作是如何实现的信息。 第3章类与对象实际上,采用面向对象方法进行系统分析与设计 时要描述的并不是一个个具体的对象。对于一个具体 的系统而言,可能存在很多具有相同特征的对象,而 且通常系统中对象的数目是不确定的。例如,对于一 个学籍管理系统,存在许多学生对象,它们具有相同的结构特征和行为特征,只是表示内部状态的数据值不同。为了描述这种相同结构特征和行为特征的对象, 面向对象方法引入了类的概念。这一点与人们在认识客观世界的事物时所采取的分类思想相同。人们在认识事物时总是将具有相同特征的事物归为一类,属于 某类的一个事物具有该类事物的共同特征。 第3章类与对象类是对一组具有相同特征的对象的抽象描述,所 有这些对象都是这个类的实例。对于学籍管理系统, 学生是一个类,而一个具体的学生则是学生类的一个 实例。一个类的不同实例具有相同的操作或行为的集 合和相同的信息结构或属性的定义,但属性值可以不同;不同的实例具有不同的对象标识。对于学生类中的每一个对象,描述它们所使用的数据结构相同,但 是值不同。在程序设计语言中,类是一种数据类型,而对象是该类型的变量,变量名即是某个具体对象的标识。 第3章类与对象因此,一个类的定义至少包含以下两个方面的描述:(1) 该类所有实例的属性或结构的定义。 (2) 该类所有实例的操作(或行为)的定义。 类是构成Java语言程序的基本单位,一个完整的 Java程序是由若干个类构成的,每个类由若干数据和方法构成,一个类的定义包含属性(数据)和方法(行为)两部分内容。 第3章类与对象3.1.3 继承性人们在对客观世界的事物进行描述时,经常采取分 类的方法。类是有层次的,即某个大类的事物可能分为 若干小类,而这些小类可能又分为若干个更小的类。 面向对象思想采纳了事物分类的层次思想,在描述 类的时候,某些类之间具有结构和行为的共性。例如, 描述教师与学生时均需描述姓名、年龄、身高、体重等 属性,将这些共性抽取出来,形成一个单独的类――人,用于描述教师类和学生类的共性。类人的结构特征和行为特征可以被多个相关的类共享,教师类和学生类继承 了类人的结构和行为特征。 第3章类与对象Java语言支持类的继承,可以从一个类中派生出 一个新的类,原来的类称为超类或父类,新类称为超 类的子类或派生类。子类的对象具有超类对象的特征, 同时又有其自身特有的特征。子类又可以派生出新的 子类,子类的子类也称为派生类。 利用类之间的继承关系,可以简化类的描述,提 高软件代码的可重用性。在设计一个新类时,不必从 头设计编写全部的代码,可以通过从已有的具有类似特性的类中派生出一个类,继承原有类中的部分特性,再加上所需的新特性。 第3章类与对象另外,人们在对客观世界的事物进行分类时,一 个事物可能属于多个类,具有多个类的特性。例如, 一个黑人学生,他既属于学生类,又属于黑人类。这 种情形在面向对象方法中称为多继承,即一个类同时 从多个类中派生出来,此时类的层次结构是网状的。Java语言为了不使语法过于复杂,不支持多继承,只允许子类有一个超类,称为单继承。不过,Java语 言提供了接口机制,可以在一定程度上模拟多继承。 第3章类与对象3.1.4 多态性 多态性是面向对象系统的又一重要特性。所谓多态,即一个名词可具有多种语义,如一个方法名有多种功能,或者相同的接口有多种实现方法。 在Java语言中,多态性通过方法的重载、覆盖和接 口来实现。 方法的重载是指多个方法具有相同的名称 ,但各 个方法的参数表不同,即参数的类型和参数的数量不 同。有关重载的问题将在3.3.5节讨论。 第3章类与对象覆盖是指在类的派生过程中,子类与超类的方法不仅名称相同,参数也完全相同,但它们的功能不同, 这时子类中的方法覆盖了超类中同名的方法。 接口实际上是一种特殊的类,只给出方法的名称、 参数和返回值的类型,方法的具体实现在实现该接口 的类中给出。在3.4.3节将详细介绍Java语言中接口的 使用方法。 多态性使得方法的调用更加容易、灵活和方便。 第3章类与对象3.1.5 封装 封装是一种信息隐藏技术,对象内部对用户是隐 藏的,不可直接访问;用户只能见到对象封装界面上 的信息,通过对象的外部接口访问对象。用户向对象 发送消息后,对象根据收到的消息调用内部方法作出响应。封装的目的在于将对象的使用者和对象的设计者分开,使用者无需知道对象内部实现的细节,只需 知道对象接收的消息即可。 第3章类与对象Java语言通过类来实现封装,类中定义的属性和方法分为私有的和公有的,私有属性和方法不能在对 象的外部访问,只能由类内的方法访问。而在对象的 外部,只能访问对象的公有属性和方法,只需要知道 公有属性的数据类型和名字以及公有方法的原型,至 于这些方法是如何实现的对象外部并不需要知道。这 就像人们在使用电视机时只需要通过遥控器来操作即 可,至于电视机内部细节用户则无需知道,这里遥控 器上的按钮实际上就是电视机的外部接口。 对象的封装特性可以提高模块之间的独立性,使 得系统易于调试和维护。 第3章类与对象3.2 案 例第2章给出了一些完整的Java应用程序的例子,但 这些例子并没有使用Java语言面向对象的特性,程序 的结构与C语言程序类似。下面的程序中定义了两个类, 读者可以从中了解一个典型的Java程序的结构。 第3章类与对象【程序3.1】 一元二次方程求解。//Equation.java //ch3_1 一元二次方程求解 import java.math.*;class ComplexRoot{double a,b, public ComplexRoot(double a,double b,double disc) { 第3章类与对象this.a=a;this.b=b; this.disc=}void Print(){ double real=-b/(2*a);double image=Math.sqrt(-disc)/(2*a);System.out.println(&两个复根:&+real+&+&+image+&i,&+real+&&+image+&i&);}} 第3章类与对象class RealRoot{double a,b, RealRoot(double a,double b,double disc) { this.a=a;this.b=b;this.disc= } void Print() { 第3章类与对象System.out.println(&两个实根:&+((-b+Math.sqrt(disc))/(2*a))+&,&+((-b-Math.sqrt(disc))/(2*a))); }}class OneRoot{ double a,b;public OneRoot(double a,double b){ this.a=a; this.b=b;}void Print() { 第3章类与对象System.out.println(&两个相等实根:&+(-b/(2*a)));} }public class Equation{ double a,b,c;Equation(double a,double b,double c){ this.a=a;this.b=b;this.c=c; } 第3章类与对象void Solve(){ double disc=b*b-4*a*c;if(Math.abs(disc)&1E-6){OneRoot o=new OneRoot(a,b); o.Print();}else if(disc&1E-6){ RealRoot r=new RealRoot(a,b,disc);r.Print();} 第3章类与对象else{ComplexRoot c=new ComplexRoot(a,b,disc); c.Print(); } } } //ch3_1.javapublic class ch3_1{ public static void main(String[] args) 第3章类与对象{Equation e=new Equation(1,2,1); e.Solve(); Equation e1=new Equation(2,2,1); e1.Solve();Equation e2=new Equation(1,5,1);e2.Solve(); } } 第3章类与对象上面的程序由两个源文件构成。Equation.java中定义了与一元二次方程求解有关的几个类:Equation类用 于求解方程,ComplexRoot、RealRoot、OneRoot 分别 用于在方程有两个复数根、两个不等实根和两个相等 实根时输出方程的根。在ch3_1.java中,main方法创建 Equation类的对象,调用Solve方法求解方程。 从程序3.1中可以看出,一个完整的Java程序是由 若干个类构成的,其中一个类有一个静态的main方法(在方法定义前用static修饰),程序从main方法开始执行。有关的基本语法将在3.3节中学习。 第3章类与对象3.3 类的声明与对象的创建3.3.1 类声明的基本语法 1.类的声明 Java语言类声明的完整语法很复杂,下面先介绍最 简单的形式: class 类名{类体} 第3章类与对象类体部分定义类的变量和方法。变量描述该类对象的属性,方法描述对象的行为特征,类似于C语言的 函数。Java语言中没有独立的函数和过程,所有的子程序都是作为方法定义的。例如,3.2节案例中类ComplexRoot的方法Print,同样Java语言也没有C语言 中的全局变量。 类中定义的变量和方法都是类的成员,Java语言 对类成员的访问有一定的权限限制。在定义属性和方 法时,可以指定访问权限,Java中访问权限有private、 protected和public。如果不指定访问权限,则为friendly。 有关权限的使用将在3.3.3节中介绍。 第3章类与对象2.变量成员的定义 变量成员的定义形式类似于C语言中的变量定义, 例如3.2节案例中ComplexRoot类的变量成员a、b和disc。 变量成员定义的一般形式为: [final] [private|protected|public] 类型 属性名[=初值];final为可选项,用final修饰的成员变量为常量。在程序中不能改变常量的值,常量必须在定义时初始化。 第3章类与对象成员变量初始化的方法与C语言相似,例如: class Point{ int x=0,y=0; } 成员变量的类型可以是Java语言中的任意数据类型, 包括简单类型、数组、类和接口。在类中,成员变量 名应该是唯一的。 第3章类与对象3.方法成员的定义 方法成员的定义形式与C语言的函数定义类似,基本形式为:[private|protected|public] 返回值类型 方法名([形式参 数表]){方法体 } 这是最基本的形式,3.2节案例中的大部分方法形 式都是如此,在后面的章节中还会陆续出现一些变化。 第3章类与对象类中的方法可以访问该类的变量成员以及方法内 定义的局部变量和形式参数。方法内定义的局部变量 以及形式参数只能在该方法内被访问。 Java语言中定义方法时必须指定返回值类型,如 果该方法没有返回值,必须定义为void。如果某方法声明了返回值类型,必须保证该方法的每一条执行路径都有返回值。例如,下面的方法定义: 第3章类与对象int func(int a,int b) { if(a&b) return a-b; } 该方法的定义是错误的,当a&=b时该方法在执行时 没有确切的返回值。这种情况在C语言中是允许的,但 在Java语言中是不允许的。下面的方法定义是正确的: 第3章类与对象int func(int a,int b){ if(a&b) return a-b; elsereturn b-a;} 正如这个例子中看到的,Java语言与C语言一样使 用return语句从被调用的方法中返回。return语句的基本 形式有两种: 第3章类与对象(1) return 表达式; 或 return(表达式); (2)。第一种形式用于有返回值的情况,第二种形式用于无返回值的情况。对于第一种情况,return后的表达 式类型应与声明的返回值类型一致,否则会产生编译错误。Java语言中的方法可以有参数也可以没有参数, 参数类型可以是简单数据类型,如整型、实型、字符 型、布尔型,也可以是复合类型,如数组、自定义类 的对象。 第3章类与对象方法被调用时,必须给定实际参数,实际参数的类型应与形式参数的类型一致。对于简单类型数据, 实际参数传递给形式参数时采用值传递,这一点与C语 言相同;如果参数为复合类型,则传递引用,此时实 参、形参为同一对象。程序3.2的运行结果可以很好地 说明这个问题。 第3章类与对象【程序3.2】 参数传递的方法。class B{ int Getb(){} void Setb(int j){b=j;}}public class MethodParm { void Method1(int Parm1,B Parm2) { 第3章类与对象Parm1=Parm1+10;Parm2.Setb(20); } public static void main (String[] args) {int a=10;B b=new B(); b.Setb(10); MethodParm obj=new MethodParm(); 第3章类与对象obj.Method1(a,b);System.out.println(a); System.out.println(b.Getb()); } }运行结果为10 20 第3章类与对象Method1方法有两个形式参数,Parm1为简单类型,Parm2为复合类型。Method1被调用时首先为Parm1分 配空间,将实际参数a的值复制给Parm1,因此Parm1与 实际参数a在内存中分别占据不同的空间,Parm1的值 的改变不影响实际参数a。而实际参数b与形式参数 Parm2代表同一对象,Parm2调用方法Setb改变其变量 成员的值,实际上改变了实参对象。 基于以上原因,Java语言通常将复合类型称为引用类型。出于安全性考虑,Java语言抛弃了C语言中的指针类型,使用引用类型来完成C语言中采用指针完成的 部分工作。 第3章类与对象方法在定义时还可能使用其他一些修饰符,例如,static、abstract、final和synchronized分别用于声明静态 方法、抽象方法、最终方法和同步方法,本书将在后 面的章节分别加以介绍。 另外,有时为了满足一定的要求,需要使用其他 语言实现一个方法,如在对硬件直接进行某些操作或 访问本地操作系统的系统功能时,可以使用native修饰 符声明一个本地方法。native方法不能移植,只能用于指定的运行平台。 第3章类与对象4.this 如果局部变量或形式参数与变量成员同名,在该 方法体中直接使用变量名则是对局部变量或形式参数 的访问。如果需要访问变量成员,可通过关键字this来 访问。例如3.2节案例中ComplexRoot类的构造方法(构造方法的作用将在3.3.2节详细介绍):public ComplexRoot(double a,double b,double disc) 第3章类与对象{ this.a=a; this.b=b; this.disc= } 这里,this.a访问当前对象的成员a,而赋值运算符 后的a表示形式参数表中的a。Java语言中类方法成员调 用时必须通过该类对象调用,例如3.2节案例中main方 法中的语句: e.Solve(); 第3章类与对象其中,e为Equation类对象,Solve为Equation类的 方法成员,在成员方法中this指代当前对象。在Solve方法执行时,this指代对象e。看下面的例子: 第3章类与对象class A{ int a=3; public void Print(){System.out.println(&a=&+a);} } Print方法中的a相当于this.a,该方法中无同名的局 部变量,不会引起混淆,因此无需使用this。 第3章类与对象3.3.2 类的构造方法与对象的初始化类定义了一类对象的特性,每一个对象都是相应 类的实例。定义一个类后,就可以定义对象,然后访 问对象的方法和变量成员了。 1.new运算符Java语言使用new运算符创建对象。例如,3.2节案例的main方法中定义对象的语句 Equation e=new Equation(1,2,1); 创建了一个Equation类的对象,也可以写为下面的形式: 第3章类与对象Ee=new Equation(1,2,1); 即首先声明一个Equation类对象的引用e,与定义 简单数据类型变量不同,这里尚未创建Equation类的对 象。变量名e只是程序中访问对象的一条途径,并不是 对象本身,执行下面的语句后e、e1表示同一个对象: Equation e1=e; 这一点与C/C++语言不同,Java语言将这类数据类型称为引用类型,与C/C++中的指针相似。引用类型变量在未赋值前,其值为null。 第3章类与对象定义对象引用后,用new运算符完成对象的创建工作,分配存储空间,并对其初始化。new运算符创建对 象的一般方法为: 变量名=new 类名([构造方法实参表]); 类名可以是系统预定义的类,也可以是自定义的类。括号中是传递给构造方法的实参,用于初始化该对象。 第3章类与对象2.构造方法构造方法是一种特殊的方法,创建对象时被自动 调用。与一般的方法不同,它没有返回值类型的说明, 方法体中也不可以用return语句带回返回值。构造方法 的方法名与类名相同,3.2节案例中的ComplexRoot、 RealRoot、OneRoot三个类中都定义了构造方法。 如果一个类定义了构造方法,则在创建该类对象 时必须按照构造方法的要求给出实参。例如3.2节案例中Equation类中创建OneRoot类对象的语句: 第3章类与对象OneRoot o=new OneRoot(a,b);其中,a、b为传递给构造方法的参数。 Java语言允许一个类有多个构造方法,只要这些方法的参 数形式不同即可。例如: class Point{int x,y;Point(int x,int y){this.x=x;this.y=y;} Point(){x=y=0;} } 第3章类与对象下面的语句在创建Point类对象时分别调用不同的 构造方法:Point p1=new Point(10,10);Point p2=new Point();在构造方法中可以通过this关键字调用该类中其他 的构造方法。例如,上面的例子可改写为下面的形式: class Point{ int x,y;Point(int x,int y){this.x=x;this.y=y;}Point(){this(0,0);} } 第3章类与对象第二个构造方法调用了第一个构造方法,this后面括号中内容为传递给第一个构造方法的实参。如果该 构造方法中还有其他的语句,应保证将this语句放在最 前面。 3.对象初始化 Java语言提供了三种初始化对象的方法,除了上 面介绍的构造方法外,还可以采用下面两种方法: (1) 定义变量成员时赋初值;(2) 在类体中的初始化程序块。 第3章类与对象【程序3.3】 对象的初始化。//ch3_3.java 对象的初始化方法演示 class A{int x=5;{ //初始化程序块开始 System.out.println(x); x=6; System.out.println(x);}{//初始化程序块结束A(int i) 第3章类与对象x=i;System.out.println(x); }}public class InitDemo { public static void main (String[] args) {A a=new A(7);} } 第3章类与对象程序运行结果为: 567 从程序3.3的运行结果可以看出,Java程序在创建 对象时首先分配空间,然后按照类中定义的成员变量 的初值初始化对象相应的成员,然后执行类中的初始 化程序块,最后执行构造方法。 第3章类与对象4.对象的清除与C/C++语言不同,Java语言中对象的清除是自动 进行的,当系统内存用尽或用户在程序中调用 System.gc时,Java运行系统启动垃圾收集机制,自动 回收不再使用的对象。垃圾收集器可以自动判断哪些 对象不再使用,例如,程序片断 A a=new A(); a=new A(); 第3章类与对象在内存中创建了两个A类对象,执行该程序片断 之后,第一次创建的A类对象在程序中无法再访问, Java垃圾收集器将自动收回该对象占用的空间。对不 再使用的对象,程序中可以将对该对象的引用赋值为 null,以释放资源。 第3章类与对象Java语言允许用户为每个类定义一个特殊的方法finalize(),当垃圾收集器清除该类对象时将调用该方法, 如果用户有一些特殊的清除工作可安排在finalize方法中。 但是,用户无法预测finalize()方法被调用的时间,即使 调用System.gc强制启动垃圾收集,也可能因为其他任 务的优先级高于垃圾收集任务,而不能立即启动。因此, 一些与时间相关的代码不应加入到finalize()方法中。 第3章类与对象3.3.3 对象的使用在对象创建之后,就可以使用该对象了,可以访 问对象的变量成员和方法成员。访问成员的基本语法 形式如下: 对象名.变量成员名对象名.方法成员名([实际参数表])在前面的例子中已多次出现了访问对象成员的语 句,例如3.2节案例中的语句 e.Solve(); 该语句说明访问e的方法成员Solve。 第3章类与对象在访问对象的方法或成员时,存在一个访问权限 的问题,即对象之间和对象内部哪些成员是可以访问 的,哪些是不可以访问的。表3.1是Java语言中类的成 员的访问范围。 第3章类与对象表3.1 类的成员的访问范围访问权限修饰符 类内 子类 包内其他类 其他包内的类public√√√√*privateprotected friendly√√ √ √* √* √ √ 第3章类与对象表3.1中,“√”表示允许访问,“√*”表示访问有 一定的限制条件。包及子类的访问权限将在3.4 、3.5节 详细介绍,本节首先介绍同一包中没有继承关系的类之 间成员访问的权限。 同一包中没有继承关系的类之间成员访问的权限比较简单,类的方法成员可以访问所在类的其他方法成员和变量成员,而类的外部不可以直接访问private成员。 第3章类与对象【程序3.4】 成员访问权限。 //ch3_4 成员访问权限演示 VistMember.java class A{ private int PrivateMember=0; public int PublicMember=0; int FriendMember=0; void Copy(A AObject){ 第3章类与对象PrivateMember=AObject.PrivateM//访问同类对象的private成员 PublicMember=AObject.PublicM//访问同类对象的public成员 FriendMember=AObject.FriendM//访问同类对象的friendly成员}} class B{ private int PrivateMember=0; public int PublicMember=0; int FriendMember=0; void CopyA(A AObject) 第3章类与对象{PrivateMember=AObject.PrivateM //错误,访问另一个类对象的private成员 PublicMember=AObject.PublicM //访问另一个对象的public成员FriendMember=AObject.FriendM//访问另一个对象的friendly成员 } } public class VistMember 第3章类与对象{public static void main (String[] args) {A aobj=new A();aobj.PublicMember = 20; aobj.FriendMember = 30;A aobj2=new A();aobj2.Copy(aobj); B bobj=new B();bobj.CopyA(aobj);} } 第3章类与对象该程序使用Visual J++编译提示如下错误信息: Cannot access private member &#39;PrivateMember&#39; in class &#39;A&#39; from class &#39;B&#39; Java语言引入了一个与对象有关的运算符 instanceof,用来测试一个指定的对象是否是指定类的实例,若是,则返回true;否则,返回false。例如:if(obj1 instanceof Class1){ } obj1为对象名,Class1为类名,若obj1为Class1类 的对象,则执行大括号中的语句。 第3章类与对象3.3.4 静态成员从前面的介绍可以知道,对象创建之后,Java程序 通过对象调用方法成员,在方法中使用变量成员名访 问当前对象的成员。不过,在前面的例子中,有一个 例外的情况,就是main方法,它是程序执行的入口点, Java程序开始执行时,并没有创建它所在类的对象。 在3.2节案例中,main方法为类ch3_1的成员方法,程序 在执行main方法时并没有创建类ch3_1的对象。main方法与其他方法的不同之处在于定义时前面有修饰符static,它是一个静态方法。Java语言允许用 static修饰符定义静态的变量成员和方法成员。 第3章类与对象1.静态变量成员 静态的变量成员通常称为类变量,而非静态的变 量成员称为实例变量。Java语言在创建对象时不为静 态变量成员分配空间,而只为非静态变量成员分配空 间。因此,静态变量成员不依赖某一个具体的对象,即使没有创建一个它所属类的对象,它也是存在的,只要该类的代码装入,则该静态变量就是存在的,就 可以使用。 第3章类与对象因为静态变量成员不依赖于具体的对象,在访问时可以不像非静态变量成员那样通过对象访问。静态 变量成员的访问方法为 类名.静态变量成员名 Java程序中的变量通常是该类对象需要共享的成员,程序3.5的MyClass类中定义了一个静态的变量成员count,用于统计该类对象的数目。MyClass类装入 时,count成员初始化为0,以后每创建一个MyClass对象(注意:不再为count成员分配空间, 第3章类与对象也不再初始化)都调用构造方法,将count的值加1。如 果将该变量成员定义为非静态的,则每创建一个该类 对象,都有属于该对象的count成员,它们相互之间没 有关系,无法实现对象计数器功能。 第3章类与对象【程序3.5】 对象计数器。//ch3_5 静态变量的作用 NumberOfClass.java class MyClass{ static int count=0; public MyClass(){count++;}public void output(){ System.out.println(&You have got &+count+& objects of MyClass&); } 第3章类与对象}public class NumberOfClass { public static void main (String[] args) { MyClass c1,c2,c3,c4; c1=new MyClass(); c1.output(); c2=new MyClass(); c2.output();c3=new MyClass();c3.output(); c4=new MyClass();c4.output(); 第3章类与对象}} 程序运行结果为: You have got 1 objects of MyClass You have got 2 objects of MyClassYou have got 3 objects of MyClassYou have got 4 objects of MyClass 第3章类与对象前面例子中多次使用了System.out.println方法来输 出 数 据,其 中 System为Java 系统预定义的类 ,out为System类的静态变量成员。程序中使用它向标准输出设备输出数据,无需创建System类对象即可直接使用。 而在C/C++语言中类似的功能是通过系统预定义的全局变量来实现的,例如C语言中的文件指针stdout、C++的流对象cout,而Java语言不允许定义全局变量,所有 变量都必须在类中定义。 第3章类与对象Java语言中static经常与final一起使用,定义一些 需要共享的常量,例如在计算圆的面积、周长以及球 的体积时都会使用到圆周率,如果将其说明为非静态 的变量成员,则在每次使用前都必须创建该常量定义 所在类的对象,显然很不方便,同时也浪费存储空间。 程序3.6用于输出Java语言中类Integer中定义的静态常 量MAX_VALUE、MIN_VALUE的值。 第3章类与对象【程序3.6】 静态变量的使用。//ch3_6 静态变量的使用 public class Class1 { public static void main (String[] args) { System.out.println(&The &+Integer.MAX_VALUE ); System.out.println(&The &+Integer.MIN_VALUE ); } } maximum minimum integer integer is is 第3章类与对象2.静态方法成员 静态方法与静态变量类似,不依赖于具体的对象,在调用时直接通过类名来调用:类名.静态方法名([方法的参数表]) 正如前面所说,main方法不依赖于任何对象直接 被调用,因此必须将其定义为静态方法。 静态方法在调用时不通过对象调用,因此在定义 静态方法时,在方法体中不能使用this,因为对静态方 法来说,不存在当前对象,同样也不能直接访问所在 类的非静态变量成员及方法成员。 第3章类与对象【程序3.7】 静态方法的使用。//ch3_7 StaticMethod.java import java.math.*; public class StaticMethod {double RStaticMethod(double r) { Radius=r; }static double CircleArea(double r) 第3章类与对象{return Math.PI*r*r; } double Area() {return Math.PI*Radius*R} public static void main (String[] args) { 第3章类与对象System.out.println(&Area=&+CircleArea(2.0)); //直接访问静态方法成员 StaticMethod obj=new StaticMethod(2.0); System.out.println(&Area=&+obj.Area()); //通过对象访问非静态方法成员 } } 第3章类与对象Java语言通常将一些公用的方法定义为静态方法, 例如求数学函数的值,它们不依赖于具体的对象,如 果定义为非静态的成员,则需要在创建一个对象后才 能访问。Java API提供的Math类封装了常用的数学函数 和数学常量,在编程时只要引入该类就可以直接使用, 3.2节案例中求平方根时就使用了Math.sqrt方法,程序 3.7中则使用了常量Math.PI。 第3章类与对象3.3.5 类内方法的重载Java语言允许一个类有多个同名的方法成员,这 些同名的方法具有不同形式的参数,在调用时只需带 入不同的实参,Java编译器就可以根据实参的类型确 定调用哪一个方法成员。3.3.2节中讲到的一个类有多 个构造方法实际上就是重载。 类内方法重载一个最常见的例子就是前面使用的 System.out.println方法,在前面的程序中用它来输出整型数据、实型数据、字符串等。下面是重载的println方法的类型: 第3章类与对象public void println() public void println(boolean x) public void println(char x) public void println(int x) public void println(long x) public void println(float x) public void println(double x)public void println(char x[])public void println(String x) public void println(Object x) 第3章类与对象方法重载为程序调用带来了方便,用户无需为不 同类型的数据选择输出方式,只需使用同一个方法即 可实现不同类型数据的输出。 Java编译器对重载方法匹配时首先根据实参类型 寻找形参类型与其完全匹配的方法,如果找不到,则 按如下原则对实参作类型转换: (1) 对于简单类型,按照byte、short、int、long、 float、double的顺序进行转换;(2) 如果实参为布尔型,不进行转换; (3) 如果实参为复合数据类型,可以将子类对象转 换为超类对象。 第3章类与对象如果按以上原则对实参进行类型转换仍然找不到匹配的重载方法,则认为是错误。程序3.8演示了方法 重载中参数匹配的方法,OverLoad类有两个同名的方 法成员max,main方法中多次调用了max。第一次调用, 两个实参为int类型,匹配第一个max方法;第二次调用, 两个实参为double类型,匹配第二个max方法;最后一 次调用,第一个实参为int类型,第二个实参为double类 型,没有参数类型完全匹配的max方法,Java编译器将 第一个实参转换为double类型后与第二个max匹配。 第3章类与对象【程序3.8】 类内方法重载。//ch3_8 类内方法重载演示 OverLoad.java public class OverLoad { int ix,double dx,OverLoad(int ix,int iy,double dx,double dy) { 第3章类与对象this.ix= this.iy= this.dx= this.dy= 第3章类与对象}int max(int a,int b) { if(a&b)else } double max(double a,double b) { 第3章类与对象if(a&b) }public static void main (String[] args){ OverLoad obj=new OverLoad(3,4,5.0,6.0); 第3章类与对象System.out.println (&the max integer is &+obj.max(obj.ix,obj.iy)); System.out.println (&the max double is &+obj.max(obj.dx,obj.dy)); System.out.println(&The max is &+ obj.max(obj.max(obj.ix,obj.iy),obj.max(obj.dx,obj.dy))); }} 第3章类与对象运行结果为: the max integer is 4the max double is 6.0The max is 6.0 第3章类与对象使用方法重载还应注意:(1) Java编译器对实参进行类型转换时,应注意避 免二义性。例如下面的程序片段: class A{ void m(int a,double b){} void m(double a,int b) { 第3章类与对象} public static void main (String[] args){A obj=new A(); obj.m(2,3); } } 第3章类与对象类A定义了两个同名方法m,在main方法中调用时 两个实参为int类型,由于没有参数类型完全匹配的重 载方法,因此Java编译器尝试对实参类型进行转换, 这时有两种转换途径:将第一个实参转换为double类型 与第二个m匹配,或者将第二个参数转换为double类型与第一个m匹配。Java编译器无法确定选择哪一种转换途径,这是不允许的。 第3章类与对象(2) 类内方法重载时,不允许参数表完全一致,而 只是返回值类型不同。例如: class A{ void m(int a,int b) {}int m(int a,int b) { } } 第3章类与对象3.3.6 字符串 本书第2章对字符串常量作了简单介绍,Java语言 的字符串常量在书写方式上与C语言很相似,但是它们 在计算机内部的存储方式不同。Java语言定义了专门 的字符串类型String,它是一种复合类型,一个字符串变量就是一个String类的对象,而C语言中的字符串只是一块连续的存储空间,用于存储若干个字符类型的 数据。 第3章类与对象1.创建String类对象String类对象的创建与其他类型对象创建的方法是相同的, 例如: String str=new String(&This is a string&); String类的构造方法有多个,常用的形式有:public String()public String(String value) public String(char value[]) 第3章类与对象由于字符串类型在程序设计中经常会用到,因而Java语言还提供了一种简便的方法来初始化String对象。 例如: String str=&This is a string&; 另外,在程序中大部分需要使用String类对象的地方可以直接使用字符串常量。例如:System.out.println(&This is a string&); 这里,Java语言用字符串常量&This is a string&构造 一 个 String 类 对 象 , 然 后 将 该 对 象 作 为 实 参 传 递 给 println方法。 第3章类与对象2.获取字符串的信息创建了String对象后,就可以通过调用String类的方 法成员来对字符串进行各种操作或者获取有关字符串 的信息了。例如,通过调用length方法可以获得字符串 的长度: String str=&A String Object&; int len=str.length(); startsWith方法可以判断一个字符串的前缀是否为 指定的字符串: String str=&Java String&; boolean result=str.startsWith(&Java&); //result=true 第3章类与对象endsWith用于确定字符串是否以给定的字符串结尾:String str=&This is a string&; boolean result=str.endsWith(&String&); boolean result=str.endsWith(&string&); //result=false //result=true如果需要比较两个字符串的值是否相等,可以使用equals方法,也可以直接使用关系运算符==。例如:String firstName=&Nancy&; 第3章类与对象if(firstName.equals(&Nancy&)){//条件满足,执行此程序段 } equals方法区分大小写,如果不区分大小写比较两 个字符串是否相等,可以使用方法equalsIgnoreCae。 第3章类与对象3.字符串的操作String类还提供了一些方法用于从字符串中抽取字 符串的某些部分,如一个字符或一个子串,下面介绍 一些常用的方法。 charAt用于抽取指定位置的字符,例如:String str=&Java string&;char c=str.charAt(3); //c=&#39;a&#39; 该方法的参数为希望抽取的字符所在的位置,这 里位置是从0开始计数的。 第3章类与对象subString用于提取字符串中从某个位置开始的若干个字符,例如: String str=&Tom and Jerry&; String str1=str.subString(4); //str1=&and Jerry& String str2=str.subString(4,7); //str2=&and&对字符串的操作( 如合并字符串、替换字符) ,String类也提供了一些方法,例如:replace方法可以将 字符串中的一个字符替换为另一个字符,concat方法可以合并两个字符串。 第3章类与对象replace方法有两个字符类型的参数,第一个为原来的字符,第二个为替换用的字符。例如: String str=&java&; String str1=str.replace(&#39;a&#39;, &#39;A&#39;); //str1=&jAvA&; concat方法有一个参数,为需要合并的字符串。例如:String str=&First&;String str1=str.concat(&Program&); //str1=&First Program& 第3章类与对象需要注意的是:String类对象创建后,字符串的值是不能改变的,replace、concat方法并不改变原来字符 串的值,而是创建了一个新的String类对象作为返回值。 如果希望字符串在创建后值可以改变,应使用 StringBuffer类。 Java语言中可以直接使用+运算连接两个字符串, 例如: String str=&First&;String str1=str+& Program&; //str1=&First Program& 第3章类与对象Java语言还可以将一个字符串与其他类型的数据进 行加法运算,例如3.2节案例中的语句: System.out.println(&两个相等实根:&+(-b/(2*a))); Java语言将后面其他类型的数据转换为字符串后与 第一个字符串连接。 第3章类与对象【程序3.9】 String类的使用。 //ch3_9 StringClass.java public class StringClass{String myString=&1&; public static void main (String[] args) { StringClass myObj = new StringClass();myObj.stringModifier(myObj.myString);StringClass myObj = new StringClass(); myObj.stringModifier(myObj.myString); 第3章类与对象System.out.println(& &+myObj.myString);} void stringModifier(String theString) { theString = theString+&2&;System.out.print(theString);} } 程序的运行结果为 12 1 第3章类与对象4.字符串与其他类型数据的转换 程序设计中经常需要将字符串转换为整型或实型 数据,例如,从键盘输入一个整数,只能先读入字符 串,然后将其转换为整数,因为System.in.read方法只 提供了读取字符的方法;同样,反向的转换也经常会用到,例如,在Java Applet中将数据转换为字符串后输出。Java语言中这样的转换都可以通过简单数据类型 的包装类来实现。 第3章类与对象Java语言为每一个简单数据类型定义了一个类(如int 对 应 Integer , float 对 应 Float) , 称 为 包 装 类 (Wrapper Class)。包装类为与该类型相关的方法和变量提供一个归属,如字符串转换和值域常量。如果需要将简单类型变量转换为字符串,可以首 先创建一个包装类对象,然后调用该对象的toString方 法即可。例如: String IntStr = new Integer(123).toString();String DoubleStr = new Double(123.456D).toString(); 第3章类与对象实际上,Java语言中的每一个对象都有一个 toString() 方法。例如: Date day = new Date(); //Date为Java类库中处理日期的类 System.out.println(day);这里的输出语句相当于System.out.println(day.toString()); 前面提到,Java语言对+运算符的功能进行了扩展, 可以允许字符串与int、float等类型的数据连接,实际 上这里使用了包装类,例如: 第3章类与对象String str=&&+5; 相当于: String str=&&+(new Interger(5).toString()); 即两个 String 的相加。 包装类的另一种构造方法以字符串作参数,可以 使用该构造方法创建包装类对象,将字符串转换为简 单类型数据。例如: int intNumber = new Integer (&10&).intValue(); boolean con = new Boolean (&true&).booleanValue(); 第3章类与对象这里,Boolean为boolean类型的包装类,常用的包装类还有:Character包装char,Byte包装byte,Long包 装long 。从 包 装 类 型 对 象 获 取 基 本 类 型 值 的 方 法 为 typeValue , 其 中 type 为 相 应 的 数 据 类 型 。 例 如 : intValue获取int值,charValue获取char值,doubleValue 获取double值。 另外,String类还提供了静态的方法valueOf,可以 用来将基本类型的值转换为字符串。valueOf有多种形式,分别用于转换不同类型的数据,例如: 第3章类与对象● public static String valueOf(boolean b); ● public static String valueOf(char c);● public static String valueOf(int i);● public static String valueOf(long l); ● public static String valueOf(float f); ● public static String valueOf(double d)。 第3章类与对象5.StringBuffer类 String类是字符串常量,对象创建后值不可更改。而 StringBuffer是字符串变量,它的对象是可以扩充和修改 的。StringBuffer类的构造函数主要有以下几种形式: ● public StringBuffer():创建一个空的StringBuffer类的对象。● public StringBuffer( int length ):创建一个长度为 参数length 的StringBuffer类的对象。 第3章类与对象● public StringBuffer( String str ):用一个已存在 的字符串常量来创建StringBuffer类的对象。 StringBuffer类的主要方法有: ● public String toString():转换为String类对象并 返 回 。 由 于 很 多 类 的 方 法 需 要 String 类 的 对 象 , 如Graphics类的方法drawString,经常要将StringBuffer类的对象转换为String类的对象。 第3章类与对象● public StringBuffer append( boolean b )。● public StringBuffer append( char c )。 ● public StringBuffer append( int i)。 ● public StringBuffer append( long l )。 ● public StringBuffer append( float f )。● public StringBuffer append( double d )。 第3章类与对象以上六种方法可分别将boolean、char、int、long、 float和double 六种类型的变量追加到StringBuffer类的 对象的后面。例如: double d=123.4567; StringBuffer sb=new StringBuffer();sb.append(true);sb.append(&#39;c&#39;).append(d).append(99);//sb的值为 truec123.456799 第3章类与对象● public StringBuffer append( String str ):将字符串常量 str追加到StringBuffer类的对象的后面。 ● public StringBuffer append( char str[] ):将字符数组str 追加到StringBuffer类的对象的后面。 ● public StringBuffer append( char str[], int offset, int len ):将字符数组str从第offset个开始取len个字符,追加到StringBuffer类的对象的后面。 第3章类与对象● public StringBuffer insert( int offset, boolean b )。● public StringBuffer insert( int offset, char c )。 ● public StringBuffer insert( int offset, int i )。 ● public StringBuffer insert( int offset, long l )。 ● public StringBuffer insert( int offset, float f )。● public StringBuffer insert( int offset, double d )。● public StringBuffer insert( int offset, String str )。 ● public StringBuffer insert( int offset, char str[] )。 第3章类与对象以 上 8 种 方 法 分 别 将 boolean 、 char 、 int 、long 、 float、double类型的变量、String类的对象或字符数组 插入到StringBuffer类的对象中的第offset个位置。例如: StringBuffer sb=new StringBuffer(&abfg&); sb.insert(2, &cde&);//sb的值为abcdefg● public int length():返回字符串变量的长度,用法与String类的length方法类似。 第3章类与对象3.3.7 数组 与其他程序设计语言一样,Java语言也支持数组。 数组是一组类型相同的有序数据,数组中的每个元素 具有相同的数组名,通过下标来唯一地确定数组中的 元素。与C语言不同,Java语言中的数组是一个可以动态创建的对象。在Java语言程序中可以使用一维数组或 多维数组。 第3章类与对象1.一维数组定义一维数组定义形式为 type arrayName[]; 其中,类型(type)可以为Java中的任意数据类型, 包括简单类型和复合类型;数组名arrayName为一个合法的标识符,[]指明该变量是一个数组类型变量,可以写在数组名后,也可以写在数组名前。例如: int []intA 第3章类与对象声明了一个整型数组,数组中的每个元素为整型数据。与C/C++不同,Java在数组的定义中并不为数组 元素分配内存,因此,[]中不用指出数组中元素的个数, 即数组长度,而且对于如上定义的一个数组是不能访 问它的任何元素的。数组定义后还必须用运算符new为 它分配内存空间,其格式如下: arrayName=new type[arraySize]; 其中,arraySize指明数组的长度,为int类型常量或表达式。如intArray=new int[3]; 第3章类与对象为一个整型数组分配3个int型整数所占据的内存空 间。这两部分也可以合在一起,定义数组时直接为其 分配空间,格式如下: type arrayName = new type[arraySize]; 例如:int intArray[]=new int[3]; 第3章类与对象2.引用数组元素定义数组并为其分配了内存空间后,就可以引用 数组中的每一个元素了。数组元素的引用方式为 arrayName[index] 其中:index为数组下标,它可以为int类型常量或表达式,如a[3],b[i](i为整型),c[6*i]等。 第3章类与对象Java语言数组的下标从0开始,一直到数组的长度 减1,数组的长度可以通过属性length获得。对于上面 例 子中 的数 组 intArray来 说, 它有3个 元 素,分 别 为 intArray[0]、intArray[1]和intArray[2]。 与C/C++中不同,Java对数组元素要进行越界检查以保证安全性。如果访问数组元素时下标越界,将引发一个异常(有关异常的处理,参考本书第6章)。 第3章类与对象【程序3.10】 数组的使用。 //ch3_10 ArrayTest.java public class ArrayTest{ public static void main(String args[]){ int a[]=new int[5]; for(i=0;i&5;i++)a[i]=i;System.out.println(&数组长度为:&+a.length); 第3章类与对象for(i=0;i&=a.i++)System.out.println(&a[&+i+&]=&+a[i]); } } 使用Visual J++ 6.0调试该程序后,首先输出结果如下:数组长度为:5 第3章类与对象a[0]=0 a[1]=1 a[2]=2 a[3]=3 a[4]=4 然后出现图3.1所示的对话框。因为程序中访问了a[5], 已越界,因此产生错误。 第3章类与对象图3.1 数组下标越界异常 第3章类与对象3.数组的初始化 可以按照上述的例子对数组元素进行赋值,也可 以在定义数组的同时进行初始化。 例如: int a[]={1,2,3,4,5};用逗号(,)分隔数组的各个元素,系统自动为数组分配一定空间,无需再使用new分配空间。 第3章类与对象4.数组举例 下面看几个使用一维数组的例子。 【程序3.11】 用数组计算Fibonacci数列。 //ch3_11 Fibonacci.java public class Fibonacci{public static void main(String args[]){ int f[]=new int[10]; f[0]=f[1]=1; for(i=2;i&10;i++) 第3章类与对象f[i]=f[i-1]+f[i-2]; for(i=1;i&=10;i++) System.out.println(&F[&+i+&]=&+f[i-1]); } } 第3章类与对象【程序3.12】 冒泡法排序。 对给定数组的元素从小到大排列,采用冒泡法排序,相邻的两个元素进行比较,并把小的元素交到前面。//ch3_12 BubbleSort.java public class BubbleSort{ public static void main(String args[]){ int i,j;int intArray[]={20,1, -11,80,25};int l=intArray. 第3章类与对象for(i=0;i&l-1;i++) for(j=0;j&l-i-1;j++) if(intArray[j]&intArray[j+1]){ int t=intArray[j]; intArray[j]=intArray[j+1]; intArray[j+1]=t; }for(i=0;i&l;i++)System.out.println(intArray[i]+&&); 第3章类与对象} } 运行结果为: -11 1 20 2580 第3章类与对象5.多维数组 Java语言将多维数组看作数组的数组。例如,二维 数组可以看成一个特殊的一维数组,其每个元素又是 一个一维数组。下面简单介绍一下二维数组的使用。 二维数组的定义方式为 type arrayName[][]; 例如: int intArray[][];与一维数组类似,使用运算符new为二维数组分配 内存后,才可以访问每个元素。二维数组分配内存空 间可采用下面两种方法: 第3章类与对象(1) 直接为每一维分配空间,如 int a[][]=new int[2][3];(2) 从最高维开始,分别为每一维分配空间。如:int a[][]=new int[2][]; a[0]=new int[3]; a[1]=new int[4]; 第3章类与对象这里,二维数组a的第0行有3个元素,第1行有4个元素。这一点与C/C++是不同的,在C/C++中必须一次 指明每一维的长度,而且二维数组每一行的长度必须 是相等的。 对二维数组中的每个元素,引用方式为 arrayName[index1][index2],其中,index1、index2为下 标,可为int型常量或表达式,如a[2][3]。同样,每一 维的下标都从0开始。 第3章类与对象二维数组也可以在定义时初始化,例如: int a[][]={{1,2},{3,4},{5,6}};定义了一个3×2的数组,并对每个元素赋值。程序3.13用二维数组实现矩阵相乘。 第3章类与对象【程序3.13】 矩阵相乘。两个矩阵Am×n、Bn×l相乘得到Cm×l,每个元素 Cij=aik×bkj //ch3_13 矩阵相乘 MatrixMul.java public class MatrixMul{public static void main(String args[]){ 第3章类与对象int i,j,k; int a[][]=new int[2][3]; int b[][]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int c[][]=new int[2][4]; for(i=0;i&2;i++) for(j=0;j&3;j++) a[i][j]=(i+1)*(j+1);for(i=0;i&2;i++){for(j=0;j&4;j++){ 第3章类与对象c[i][j]=0;for(k=0;k&3;k++) c[i][j]+=a[i][k]*b[k][j]; } }System.out.println(&***Matrix A***&);for(i=0;i&2;i++){ for(j=0;j&3;j++) System.out.print(a[i][j]+& &); System.out.println(); 第3章类与对象}System.out.println(&\n***Matrix B***&); for(i=0;i&3;i++){ for(j=0;j&4;j++) System.out.print(b[i][j]+& &);System.out.println();} System.out.println(&\n***Matrix C***&); for(i=0;i&2;i++){ for(j=0;j&4;j++) 第3章类与对象System.out.print(c[i][j]+& &); System.out.println();}} } 运行结果为: ***Matrix A***123246 第3章类与对象***Matrix B***
10 11 12 ***Matrix C*** 38 44 50 56 76 88 100 112 第3章类与对象3.4 继 承3.4.1 继承的基本语法 3.1.3节介绍了面向对象方法的重要特性――继承性, 利用继承性可以提高代码的可重用性,提高软件开发 的生产率。Java语言支持继承机制,在定义类时通过 关键字extends指定超类的名称即可。 第3章类与对象1.子类的定义子类定义的基本语法形式为: class 子类名 extends 超类名{ } Java语言不支持多继承,因此超类名只有一个。子类继承超类的特性,也可以通过定义新的成员修改超类的特性或增加新的特性。 第3章类与对象Java语言在为子类对象分配空间时,不仅为子类 中新定义的成员分配空间,同时也为超类中定义的成 员(包括public、protected、private以及friendly成员)分 配空间,在一定程度上可以认为一个子类对象内部包 含一个超类对象。 第3章类与对象Java语言允许将一个子类对象作为超类对象使用,当需要时可以进行隐含的类型转换。例如,若将一个 方法的形式参数定义为超类对象,则在调用时可以将 子类对象作为实际参数。Java语言中的各种类型的对 象都可以当作Object类的对象使用,Object类中定义了 Java语言对象的基本特性,例如前面用到的toString方 法。如果在定义一个类时没有用extends关键字指定超 类,则该类的超类为Object。 第3章类与对象超类中定义的成员根据其权限的不同在该类中的访问权限也不同,从表3.1中可以看出超类中定义的 private成员在子类定义的方法成员中是不可访问的,而 超类的public成员和protected成员可以在子类中访问, 当超类、子类在同一个包中时,friendly成员也可以在 子类中访问。 第3章类与对象子类在定义新的成员时,允许新成员与超类成员 同名。对于同名变量成员,超类中的相应成员被隐藏。 对于同名方法成员,如果参数形式相同且返回值类型 相同,则超类中该方法成员被隐藏;如果参数形式不 同,则调用时根据实参类型决定调用哪一个方法成员, 与类内方法重载相同。Java语言不允许子类与超类方 法同名,而参数形式相同但返回值类型不同。 第3章类与对象2.super 如果程序中需要访问被隐藏的同名超类成员,可 以使用关键字super,super指代当前对象中在超类中定 义的那一部分。程序3.14和3.15分别演示了如何访问超 类中同名变量成员和方法成员。 第3章类与对象【程序3.14】 用super访问超类同名变量成员。class Test{public Test(){i=10;}} public class Test1 extends Test {public Test1(){i=12.345678;}public void print() { 第3章类与对象System.out.println(&i of sub class &+i);//访问子类成员i System.out.println(&i of super class &+super.i); //访问超类成员i }public static void main (String[] args){ Test1 t1=new Test1(); t1.print(); }} 第3章类与对象【程序3.15】 用super访问超类同名方法成员。 class Test{ public Test(){i=10;} public void print(){System.out.println(&i of super class &+i); } } public class Test1 extends Test 第3章类与对象{public Test1(){i=12.345678;}public void print() { System.out.println(&i of sub class &+i); super.print(); //访问超类中定义的print方法}public static void main (String[] args) 第3章类与对象{Test1 t1=new Test1(); t1.print(); } } 第3章类与对象3.子类对象的构造 子类对象在创建时需要调用超类的构造方法来构造超类中定义的那部分成员,如果在子类中不特别声明,则调用超类的不带参数的构造方法。 如果超类没有不带参数的构造方法,必须在子类的构造方法中用super关键字指定如何调用超类的构造方法。先看下面的程序。 第3章类与对象class A{ A(int a){ this.a=a; } } class B extends A{B(int b){ this.b=b; 第3章类与对象System.out.println(&Class B&); }}public class Class1 { public static void main (String[] args) { B b=new B(10);}} 第3章类与对象该程序中类A的构造方法带有一个int类型的参数, 类B为类A的子类。使用Visual J++编译该程序,给出如 下错误信息: Class &#39;A&#39; doesn&#39;t have a constructor that matches &#39;A()&#39; 这个错误信息表明,在构造B类对象时试图调用A类不带参 数的构造 方法。程 序3.16演 示了如何 使用super关键字调用超类的构造方法。 第3章类与对象【程序3.16】 super关键字的使用。 class Test{ public Test(int i){this.i=i;} } public class Test1 extends Test {public Test1(int i,double j) 第3章类与对象{ super(i); this.j=j; } public void print() { System.out.println(&i of sub class &+i); //调用超类构造方法System.out.println(&j of super class &+j);} 第3章类与对象public static void main (String[] args) {Test1 t1=new Test1(5,3.14);t1.print(); } } 第3章类与对象4.final方法与final类通过在子类中定义与超类同名的方法成员,覆盖 超类的方法成员,改变了超类原有的特征。有时可能 程序员不希望子类修改超类原有的特性,这时可以将 对应的方法定义为最终(final)方法,子类不再可以覆盖 该方法。例如: 第3章类与对象class A{ final void Method1(){System.out.println(&This is a final method&);} } 当从A类派生子类时,子类不可以定义与Method1形式相同的方法。 第3章类与对象关键字final也可以用来修饰类的定义,将一个类定 义为最终类,则不再可以从该类派生出子类。基本语 法形式为: final class 类名{ //成员定义} 第3章类与对象5.程序举例最后再来看一个例子,该程序对3.2节的案例作了 修改。从3.2节中可以看出,Equation.java文件中定义的 ComplexRoot、RealRoot、OneRoot有很多共同的特征, 因此定义了一个描述这三个类共同特征的类Root,从 该类派生出ComplexRoot、RealRoot、OneRoot。在 Equation类的Solve方法中,定义一个Root类对象,然 后根据disc的值分别用ComplexRoot、RalRoot、 OneRoot实例化该对象,然后调用Print方法。需要特别 注意的是:此处调用的是子类中的Print方法,而不是 在Root类中定义的Print。从该程序中也可以看出,在 Java语言中可以将一个子类对象看作是一个超类对象。 第3章类与对象【程序3.17】 用继承求解一元二次方程。//ch3_17 一元二次方程求解 Equation.java import java.math.*; class Root{ public Root(double a,double b,double disc){this.a=a; this.b=b; this.disc= } 第3章类与对象void Print(){}} class ComplexRoot extends Root { public ComplexRoot(double a,double b,double disc) {super(a,b,disc);} void Print(){ double real=-b/(2*a); double image=Math.sqrt(-disc)/(2*a); 第3章类与对象System.out.println(& 两个复根 :&+real+&+&+image+&i,&+real+&&+image+&i&);}}class RealRoot extends Root{ double a,b, RealRoot(double a,double b,double disc) {super(a,b,disc);} void Print() 第3章类与对象{ System.out.println(&两个实根:& +((-b+Math.sqrt(disc))/(2*a))+&,&+((-b-Math.sqrt(disc))/(2*a))); } } class OneRoot extends Root{ public OneRoot(double a,double b,double disc){super(a,b,disc); } 第3章类与对象void Print(){ System.out.println(&两个相等实根:&+(-b/(2*a))); } }public class Equation{ double a,b,c; Equation(double a,double b,double c) { 第3章类与对象this.a=a;this.b=b; this.c=c;}void Solve() { R double disc=b*b-4*a*c;if(Math.abs(disc)&1E-6){r=new OneRoot(a,b,disc); } 第3章类与对象else if(disc&1E-6){ r=new RealRoot(a,b,disc); } else{ r=new ComplexRoot(a,b,disc); } r.Print();//此处调用子类中定义的Print方法}} 第3章类与对象3.4.2 抽象类与抽象方法 程序3.17中类Root定义了一个Print方法,但从下面的程序可以看出:该Print方法并没有被调用,程序中真正使用的是Root类的子类中定义的Print方法。这里 Root类中的Print方法实际上只是表示一种概念,输出方程根的类必须有一个方法Print。虽然在Root类中为Print方法定义了一个方法体,但该方法体并没有实际 用处,而这里的Root类也只是表示一种概念,程序中并不会创建Root类对象。 第3章类与对象对于上述这种情况,Java语言引入了抽象类和抽象方法,用于表示抽象的概念。对于Root类可以定义如下: abstract class Root{ public Root(double a,double b,double disc) {this.a=a;} abstract void Print(); }this.b=b; this.disc= 第3章类与对象其中,第一个abstract表示定义一个抽象类,第二 个abstract表示Print方法为抽象方法。如果一个类包含有抽象方法,该类必须声明为抽象类。抽象方法在定义时无需给出方法体,只要给出方 法的返回值类型和形式参数表即可。程序中不可创建抽象类对象,必须从抽象类派生出子类,在子类中实现所有抽象的方法后才可以创建子类的对象。如果子 类没有实现超类中所有抽象方法,则子类也必须定义 为抽象类。 第3章类与对象定义抽象类的目的主要是为了表达一个抽象的概 念,体现若干类之间的联系,这是Java语言多态性的 一个重要表现。程序3.18要求输出多种规则图形的面积, 对于不同的图形,计算面积的公式是不同的。程序中 为不同的图形类定义了一个共同的超类Graph,将求面积的方法定义为抽象方法,然后在子类中分别给出具体的求面积的方法。值得一提的是,程序中并没有为 每一种图形分别定义输出面积的方法,只在Graph类中定义了输出面积的方法。可以看出,继承和多态性减小了程序的代码量。 第3章类与对象【程序3.18】 求多种规则图形的面积。abstract class Graph {protected double x,y;//表示图形位置的坐标public Graph(double x,double y){this.x=x;this.y=y;} protected void changeX(double x){this.x=x;} protected void changeY(double y){this.y=y;} public abstract double area();public void PrintArea(){System.out.println(&The area is &+area());}} 第3章类与对象class MySquare extends Graph{ p public MySquare(double x,double y,double length) { super(x,y); this.length= } protected void changelength(doublelength){this.length=}public double area(){return length*} } 第3章类与对象class MyCircle extends Graph{ p public MyCircle(double x,double y,double radius) { super(x,y); this.radius= } protected void changeradius(double radius){this.radius=}public double area(){return 3.14159*radius*} } 第3章类与对象class MyRectangle extends Graph{private double a,b; public MyRectangle(double x,double y,double a,double b) { super(x,y);this.a=a;this.b=b; } protected void changelength(double length){a=} protected void changewidth(double width){b=} 第3章类与对象public double area(){return a*b;} } class MyEllipse extends Graph{ private double a,b; public MyEllipse(double x,double y,double a,double b) { super(x,y);this.a=a;this.b=b; } 第3章类与对象protected void changeA(double a){this.a=a;}protected void changeB(double b){this.b=b;} public double area(){return 3.14159*a*b;} }public class area {public static void main (String[] args) { 第3章类与对象MyCircle c1,c2; c1=new MyCircle(1,1,3);c2=new MyCircle(3,3,5);MySquare s1,s2; s1=new MySquare(2,2,4); s2=new MySquare(4,4,9); MyRectangle r=new MyRectangle(12,9,1,0.5);MyEllipse e=new MyEllipse(2,-1,3,1.9);c1.PrintArea(); 第3章类与对象c2.PrintArea(); s1.PrintArea(); s2.PrintArea(); r.PrintArea(); e.PrintArea(); } } 第3章类与对象3.4.3 接口 Java语言不支持多继承,但通过接口可以实现部分 多继承的功能。 1.接口的定义 接口与抽象类相似,也表达一个抽象的概念。接口中的所有方法都是抽象的,每一个都没有方法体。另外,接口只可以定义static final变量成员。 接口用关键字interface来定义,基本的语法形式为: 第3章类与对象interface 接口名 {//成员定义 } 接口中所有方法都是抽象的,不要使用abstract。 下面是一个简单的例子。interface Printable {public void Print(); } 第3章类与对象2.接口的实现接口的实现与继承类似,不过接口实现时使用关 键字implements而不是extends。例如: class IntClass implements Printable{IntClass(int a){this.a=a;}public void Print(){System.out.println(a);} } 该类实现了上面定义的Printable接口。 第3章类与对象当类实现特殊接口时,必须先定义该接口定义的所有抽象方法,然后才可以在该类的任何对象上调用 接口的方法。与抽象类相似,允许使用接口名作为复合变量的类型,在运行时根据对象的实际类型决定调用哪个类中定义的方法,这个过程通常称为动态联编。 例如: Printable obj=new IntClass(10); obj.Print();可以用instanceof运算符来判断某对象的类是否实现了特定的接口。 第3章类与对象一个类可以实现多个接口,多个接口名在implements后面一一列出,以逗号分隔。 例如: public class MyApplet extends Applet implements Runnable, MouseListener{}这里出现的接口Runnable、MouseListener将在以后 的章节中介绍。 第3章类与对象3.接口的派生定义接口时也可以从已有的接口派生,新的接口 包含了原来接口的所有成员。例如: interface PrintName extends Printable{ public String ClassName();}这里,接口PrintName从Printable派生而来,实现 该接口时必须实现Print方法和ClassName方法。例如: 第3章类与对象class IntClass implements PrintName{IntClass(int a){this.a=a;}public void Print(){ System.out.println(a);} public String ClassName(){return &IntClass&;}; } 第3章类与对象4.程序举例 下面看一个完整的例子,该例演示了如何定义接口、 实现接口和使用接口定义的方法。 【程序3.19】 接口的使用。 interface Shape{static double pi=3.14159;public double area(); } 第3章类与对象class Circle implements Shape{ double R Circle(double r){Radius=r;} public double area(){return pi*Radius*R} } public class ch3_19 { 第3章类与对象public static void main(String argv[]) { Shape s=new Circle(2.0); System.out.println(&Area is &+s.area()); } } 第3章类与对象3.5 包 的 使 用3.5.1 包的概念 Java程序编译后每一个类和接口都生成一个独立 的class文件。对于一个大型程序,由于类和接口的数 量很大,如果将它们全放在一起,往往显得杂乱无章, 难于管理。Java语言提供了一种解决该问题的方法:将类和接口放在不同的包中。 第3章类与对象一个包由一组类和接口组成,包内还可以有子包, 类似于目录(文件夹)中可以有若干文件和子目录(子文 件夹)一样。实际上,Java系统就是使用文件夹来存放 包的,一个包对应一个文件夹,文件夹下有若干个 class文件和子文件夹。 当要使用其他包内的类时,可以使用import语句引 入其他包内的类。本书前面例子多次出现了import语句, 例如:import java.math.*; 第3章类与对象这里,java为包名,math为java包内的子包,*表示该包中所有类,该语句引入了java.math包中的所有 类。java包是Sun公司使用Java语言开发的类的集合, 是随Java运行系统提供的,Java语言的很多功能依赖于 该包中的类。目前的Java虚拟机通常将java包以一种压 缩文件的形式存储在特定的目录中。java包中的子包 lang是自动引入的,无需使用import语句引入该包,前 面提到的String、StringBuffer、Sytem等类均在该包中 定义。 第3章类与对象import也可以引入特定的类,只要用类名取代上面 例子里的*即可。例如: import java.awt.G 包的使用可以避免名字冲突,每一个类和接口的 名字都包含在某个包中,不同的包中可以有同名的类 和接口。 在程序中使用同名类时,可以加上包名以免引起 歧义,例如java.awt.Button表示java.awt包中的Button类, 此时无需使用import语句引入该类。 另外还应注意:使用import语句引入某个包中的所 有类时并不包括该包的子包中的类。 第3章类与对象3.5.2 类的访问权限 Java语言规定只能使用其他包中公有(public)的类 和接口,即在定义该类时使用了public修饰符,例如3.2 节案例中的Equation类。 从表3.1中可以看出,使用其他包中的类时,只能访问该类的public成员。如果从其他包内的类派生出子类,则在子类中可以访问超类中的protected成员。 第3章类与对象同一个包中的类除了private成员外其他的成员均可 以访问。3.2节案例中两个文件在同一个文件夹中,其 中定义的所有类都在同一个包中。该程序编译后生成 ComplexRoot.class、RealRoot.class、OneRoot.class、 Equation.class和ch3_1.class五个文件。 第3章类与对象3.5.3 包的定义 如果希望将程序中不同的类放在多个不同的包中, 可以首先在程序的当前目录中创建相应的子目录,然 后将相应的源文件放入对应的文件夹,分别编译,同 时应在源文件前面加上相应的包定义语句。 包定义语句的格式为 package 包名; 注意:该语句必须放在程序源文件的开始,前面 不能有注释语句之外的任何语句。程序3.20是一个使用 包的完整的例子,该程序由两个文件构成,放在不同 的包中。 第3章类与对象【程序3.20】 包的定义与使用。 //PackageApplet.java import java.awt.*; import java.applet.*; import MyPackage.display. //引入displayclass类 public class PackageApplet extends Applet{public void paint(Graphics g) 第3章类与对象{Font font = new Font(&TimesRoman&,Font.PLAIN,24); g.setFont(font); displayclass myclass = new displayclass(); String s=myclass.GetDisplayText();g.drawString(s,60,80);} } 第3章类与对象// MyPackage\display\displayclass.java package MyPackage. //包定义语句public class displayclass{ public String GetDisplayText(){ return &Display Text&; }} 第3章类与对象3.6 编 程 实 例程序3.21实现了一个简易的计算器,该程序由两 个文件组成。文件Calculator.java中定义了一个类 Calculator,该类用于实现计算器的功能,但不包括输 入输出。文件AppCal.java中定义了类AppCal,其中包 含main方法。AppCal的run方法从键盘接收输入,调用 Calculator的方法进行处理。例如,若从键盘输入 3+2*3 则程序按照输入的顺序计算,最后输出结果15。 第3章类与对象【程序3.21】 简易计算器。// Calculator.java public class Calculator { private int status=0; //计算器当前状态//0表示将已计算结果放入操作数1,等待运算符,或重新输入操作数 //1表示正在输入操作数1 //2表示已输入运算符,等待输入操作数2 //3表示正在输入操作数2 第3章类与对象private String num1=&0&,num2=&&; //存储运算数private char Op; //存储运算符 public String DisplayStr=&0&; //存储运算结果 //计算器回到初始状态 public void init(){status=0; num1=&0&; DisplayStr=&0&; } 第3章类与对象//处理一个按键void KeyProcess(char key) {switch(status){case 0: if((key&=&#39;0&#39;&&key&=&#39;9&#39;)||key==&#39;.&#39;){ status=1; num1=&&+DisplayStr = num1;} else if(key==&#39;+&#39;||key==&#39;-&#39;||key==&#39;*&#39;||key==&#39;/&#39;){ 第3章类与对象Op=status=2; } case 1:if((key&=&#39;0&#39;&&key&=&#39;9&#39;)||key==&#39;.&#39;){status=1; num1=num1+ DisplayStr = num1; }else if(key==&#39;=&#39;){ 第3章类与对象status=0; }else if(key==&#39;+&#39;||key==&#39;-&#39;||key==&#39;*&#39;||key==&#39;/&#39;){Op= status=2; } 第3章类与对象case 2:if((key&=&#39;0&#39;&&key&=&#39;9&#39;)||key==&#39;.&#39;){ status=3;num2=&&+DisplayStr = num2; } else if(key==&#39;=&#39;){ status=0; } 第3章类与对象case 3: if((key&=&#39;0&#39;&&key&=&#39;9&#39;)||key==&#39;.&#39;){ num2=num2+ DisplayStr = num2; }else if(key==&#39;=&#39;){Cal(); DisplayStr = num1; status=0; } 第3章类与对象else if(key==&#39;+&#39;||key==&#39;-&#39;||key==&#39;*&#39;||key==&#39;/&#39;){Cal(); DisplayStr = num1; status=2; Op =} } } 第3章类与对象//计算结果 void Cal(){double n1 = new Double(num1).doubleValue(); //使用Double类的方法将String类型转换为double类型数据 double n2 = new Double(num2).doubleValue(); 第3章类与对象double r=0;switch(Op){ case &#39;+&#39;:r=n1+n2; case &#39;-&#39;:r=n1-n2; case &#39;*&#39;: r=n1*n2; case &#39;/&#39;: r=n1/n2; 第3章类与对象}num1=String.valueOf(r); } } //AppCal.javapublic class AppCal{ Calculator cal = new Calculator(); void run() { 第3章类与对象 do{ try{ c = (char)System.in.read(); //从键盘输入 if(c==&#39;\n&#39;) cal.KeyProcess(&#39;=&#39;);//如为回车键,计算最后结果else cal.KeyProcess(c); 第3章类与对象System.out.print(cal.DisplayStr+&#39;\r&#39;);}catch(Exception e){c=&#39;\n&#39;;} }while(c!=&#39;\n&#39;); } public static void main (String[] args){AppCal c = new AppCal(); c.run(); } } 第3章类与对象实训三 面向对象程序设计一、实训目的 1.掌握定义类、创建对象、使用类与对象的方法。 2.掌握类及其成员的修饰符的使用。 3.掌握如何定义和调用方法。 4.掌握形式参数定义,形式参数与实际参数的关系。 5.掌握静态变量与非静态变量、局部变量的使用以及静 态方法与非静态方法的使用。 第3章类与对象6.掌握构造方法的使用。 7.掌握字符串类、数组的使用。8.掌握继承和重载的概念与实现方法。9.掌握如何从已有类中派生子类。 10.掌握方法的覆盖和重载。 11.掌握定义包和接口的方法。 12.掌握多文件、多类程序编译和发布的方法。 第3章类与对象二、实训内容 1.定义并使用一个新类(使用Visual J++完成本任务请参考第1章有关内容)。(1) 使用纯文本编辑软件输入下面这个源程序,保 存为Birthday.java。 第3章类与对象public class Birthday{ public Spublic Spublic S public Birthday() { year=&0000&;month=&00&;day=&00&; } 第3章类与对象public Birthday(String y,String m,String d){ year=y;month=m;day=d; } public String getBirthday() {String fullbirthday=month+&/&+day+&/&+ } } 第3章类与对象(2) 编译这个程序,如果顺利完成,将在当前目录 下生成一个名为Birthday.class的文件。 (3) 输入以下源程序,保存为useBirthday.java。 public class useBirthday {public static void main(String argv[]){ Birthday birthday1=new Birthday(); Birthday birthday2=new Birthday(&1949&,&10&,&01&); 第3章类与对象System.out.println(birthday1.getBirthday());System.out.println(birthday2.getBirthday()); } } (4) 编译useBirthday.java后,执行以下命令运行程序:java useBirthday 第3章类与对象2.定义一个类Myclass,包含一个整型属性data和封装这两个属性的两个方法getData()和setData()。然后 编写一个使用上面定义的类Myclass的Java Applet程序, 实现数据的访问和输出。 3.编写一个类实现复数的运算。复数类Complex 的属性有: mReal:实部,代表复数的实数部分; mImage:虚部,代表复数的虚数部分。 第3章类与对象复数类Complex的方法有: Complex(double r,double i):构造函数,创建复 数对象的同时完成复数的实部、虚部的初始化,r为实 部的初值,i为虚部的初值。 getReal():获得复数对象的实部。getImage():获得复数对象的虚部。setReal(double d):将当前复数对象的实部设置为 给定的形式参数的值

我要回帖

更多关于 strconcat 的文章

 

随机推荐