第4章 类与对象 本章导读 0. 面向对象编程 1. 类声明和类体 2. 类体的构成 3. 构造方法与对象的创建 4. 对象的引用与实体 第4章 类与对象 本章导读 0. 面向对象编程 1. 类声明和类体 2. 类体的构成 3. 构造方法与对象的创建 4. 对象的引用与实体 5. 成员变量 6. 方法
7. 方法重载 8. this关键字 9. 包 10. import 语句 11. 访问权限 12. 对象的组合 13. 基本类型数据的类包装 14. 反编译和文档生成器 15. JAR文件
面向对象编程 封装 封装是面向对象方法的核心思想之一。它有两个含义: 一是指把对象的属性和行为看成为一个密不可分的整体,将这两者“封装”在一个不可分割的独立单位(即对象)中。 另一层含义指“信息隐蔽”,把不需要让外界知道的信息隐藏起来,有些对象的属性及行为允许外界用户知道或使用,但不允许更改,而另一些属性或行为,则不允许外界知晓;或只允许使用对象的功能,而尽可能隐蔽对象的功能实现细节。
子类可以继承父类的属性(数据)和功能(操作)。继承是面向对象方法中的重要概念,并且是提高软件开发效率的重要手段。 多态 多态——程序中允许出现重名现象。 Java 语言中具有操作名称的多态 & 和继承有关的多态。 返回
类 Java程序设计的基本单位是类(class),Java的源文件由若干个书写形式相互独立的类构成。 类有两个基本成员:成员变量和(成员)方法。成员变量刻画对象的属性,成员方法体现对象的功能。 类是用来定义对象的模板。可以用类创建对象,当使用一个类创建了一个对象时,我们也说给出了这个类的一个实例/创建了该类的一个实例。
4.1 类声明和类体 在语法上,类由两部分构成:类声明和类体。基本格式为: class 类名 { 类体的内容…… } 4.1 类声明和类体 在语法上,类由两部分构成:类声明和类体。基本格式为: class 类名 { 类体的内容…… } class是关键字,用来定义类。“class 类名”是类的声明部分,类名必须是合法的Java标识符。两个大括号“{”、“}”以及之间的内容称作类体。
以下是两个类声明的例子。 class Dog { … } class 机动车 {
类的名字不能是Java中的关键字,要符合标识符规定,即名字可以由字母、下划线、数字或美元符号组成,并且第一个字符不能是数字。但给类命名时,最好遵守下列习惯: 1)如果类名使用拉丁字母,那么名字的首字母使用 大写字母,如Hello、Time、,People等。 2)类名最好容易识别、见名知意。 3)当类名由几个“单词”复合而成时,每个单词的首字母要大写,如BeijingTime、AmericanGame、HelloChina等。 返回
4.2 类体的构成 类体内容可以有2种类型的成员: 1.成员变量:通过变量声明定义的变量,称作成员变量或域,用来刻画类创建的对象的属性。将在后面的第3节详细地讨论成员变量。 2.方法:方法是类体的重要成员之一。其中的构造方法是具有特殊地位的方法,供类创建对象时使用,用来给出类所创建的对象的初始状态,另一类方法,可以由类所创建的对象调用,对象调用这些方法操作成员变量形成一定的算法,体现对象具有某种功能。
下面是一个类名为“机动车”的类,类体内容的变量定义部分定义了2个float类型的变量:“weight”、“height”和一个int型变量“speed”;方法定义部分定义了3个方法:“changSpeed”、“getWeight”和“getHeight”。 成员变量的类型可以是Java中的任何一种数据类型,包括前面学习过的基本类型:整型、浮点型、字符型、数组以及后面要学习的对象及接口。 成员变量在整个类内都有效,与它在类体中书写的先后位置无关,例如,前述的机动车类也可以写成:
在定义类的成员变量时可以同时赋予初值,表明类所创建的对象的初始状态。需要注意的是。对成员变量的操作只能放在方法中,方法可以对成员变量进行操作形成算法,如: 但是不可以这样做:因为,a=12是赋值语句,不是数据的声明。类的成员类型中可以有数据和方法,即数据的定义和方法的定义,但没有语句,语句必须放在方法中。 返回
4.3 构造方法与对象的创建 类中有一部分方法称作构造方法,类创建对象时需使用构造方法,以便给类所创建的对象一个合理的初始状态。构造方法是一种特殊方法,它的名字必须与它所在的类的名字完全相同,并且不返回任何数据类型,即它是void型,但void必须省略不写。 Java允许一个类中有若干个构造方法,但这些构造方法的参数必须不同,即或者是参数的个数不同,或者是参数的类型不同。 下面的Rect类有两个构造方法:
当使用一个类创建了一个对象时,我们也说给出了这个类的一个实例。创建一个对象包括对象的声明和为对象分配成员变量两个步骤。 1.对象的声明。 一般格式为: 类的名字 对象名字; 如: Rect rectangleOne;
2.为声明的对象分配成员变量 使用new运算符和类的构造方法为声明的对象分配成员变量,如果类中没有构造方法,系统会调用默认的构造方法(默认的构造方法是无参数的,你一定还记得构造方法的名字必须和类名相同这一规定),上述的Rect类提供了2个构造方法,下面都是合法的创建对象的语句: rectangleOne =new Rect(); 或 rectangleOne =new Rect(10,20);
如果类里定义了一个或多个构造方法,那么Java不提供默认的构造方法。如果上述Rect只提供一个带参数的构造方法,代码: rectangleOne = new Rect(); 创建对象是非法的。 创建对象的代码: rectangleOne = new Rect(10,20); 会实现下述两件事: (1)为成员变量分配内存空间,然后执行构造方法中的语句 。 (2)给出一个信息,已确保这些成员变量是属于对象 rectangleOne的 。
创建对象就是指为它分配成员变量,并获得一个引用,以确保这些成员变量由它来“操作管理”。为对象分配成员变量后,内存模型由声明对象时的模型图4 创建对象就是指为它分配成员变量,并获得一个引用,以确保这些成员变量由它来“操作管理”。为对象分配成员变量后,内存模型由声明对象时的模型图4.1,变成如图4.2所示,箭头示意对象可以操作这些属于自己的成员变量。 RectangleOne 0xAA11 sideB sideA 20 10 图4.2 分配实体后的对象
3.创建多个不同的对象 一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的内存空间,因此,改变其中一个对象的状态不会影响其它对象的状态。例如,我们使用前面的Rect类创建两个对象:rectangleOne、rectangleTwo。 rectangleOne =new Rect(10,20); rectangleTwo =new Rect(33,66); 当创建对象rectangleOne时,Rect类中的成员变量sizeA、sizeB被分配内存空间,并返回一个引用给ectangleOne;
当再创建一个对象rectangleTwo时,Rect类中的成员变量sizeA、sizeB再一次被分配内存空间,并返回一个引用给rectangleTwo 。内存模型如图4.3所示。 rectangleOne rectangleTwo sideB sideA 20 10 0xAA11 0xBB42 sideB sideA 66 33 图4.3 创建多个对象
4.使用对象 对象不仅可以操作自己的变量改变状态,而且还拥有了使用创建它的那个类中的方法的能力,对象通过使用这些方法可以产生一定的行为。 通过使用运算符“.”,对象可以实现对自己的变量访问和方法的调用。 1)对象操作自己的变量(对象的属性) 2)对象调用类中的方法(对象的功能) 下面例子1中,“Ladder”类创建了2个对象:ladderOne, ladderTwo。 返回
4.4 对象的引用与实体 我们已经知道,当用类创建一个对象时,成员变量被分配内存空间,这些内存空间称做该对象的实体或变量,而对象中存放着引用,以确保这些变量由该对象操作使用。因此,如果两个对象有相同的引用,那么就具有同样的实体。 假如使用例子1“Ladder”类的构造方法创建了两个对象 t1,t2。 t1=new Ladder(11,22,33); t2=new Ladder(6,12,18);
18 12 6 height bottom above 33 22 11 height bottom above t2 0xDD t1 0xAA 0xDD 33 22 11 height bottom above
Java具有“垃圾收集”机制,Java的运行环境周期地检测某个实体是否已不再被任何对象所引用,如果发现这样的实体,就释放实体占有的内存。因此,Java编程人员不必象C++程序员那样,要时刻自己检查哪些对象应该释放内存。当把变量t2中存放的引用赋给t1后,最初分配给对象t1的成员变量(实体)所占有的内存就会被释放。 没有实体的对象称作空对象。空对象不能使用,即不能让一个空对象去调用方法产生行为。假如程序中使用了空对象,程序在运行时会出现异常:NullPointerException。 由于对象是动态地分配实体,所以Java的编译器对空对象不做检查。因此,在编写程序时要避免使用空对象。 返回
4.5 成员变量 用关键字static修饰的成员变量称作静态变量或类变量, 而没有使用static修饰的成员变量称作实例变量。例如,下述A类中,x是实例变量,而y是类变量。 class A { float x; //实例变量 static int y; //类变量 } 类变量是与类相关联的数据变量,也就是说,类变量是和该类所创建的所有对象相关联的变量,改变其中一个对象的这个类变量就同时改变了其它对象的这个类变量。
因此,类变量不仅可以通过某个对象访问也可以直接通过类名访问。 实例变量仅仅是和相应的对象关联的变量,也就是说,不同对象的实例变量互不相同,即分配不同的内存空间,改变其中一个对象的实例变量不会影响其它对象的这个实例变量。实例变量必须通过对象访问。 下面例子2中,两个“ Lader”对象共享bottom。效果如图4.7
2.常量 如果一个成员变量修饰为final,就是常量,常量的名字习惯用大写字母,例如: final int MAX; 声明常量时必须初始化。对于final修饰的成员变量,对象可以操作使用,但不能做更改操作。下面的例子给出了常量的用法。效果如图4.9
返回
4.6 方法 我们已经知道,类体内容可以有2种类型的成员:成员变量和方法。其中一部分方法称作构造方法,供类创建对象时使用,用来给出类所创建的对象的初始状态。另一部分方法可分为实例方法和类方法,类所创建的对象可以调用这些方法形成一定的算法,体现对象具有某种功能。当对象调用方法时,方法中出现的成员变量就是指分配给该对象的成员变量。对象不可以调用构造方法,构造方法是专门用来创建对象的。 方法的定义包括两部分:方法声明和方法体。一般格式为:
最基本的方法声明包括方法名和方法的返回类型,返回类型也简称作方法的类型。如: float area() { …. 方法声明部分 { 方法体的内容 } 1.方法声明和方法体 最基本的方法声明包括方法名和方法的返回类型,返回类型也简称作方法的类型。如: float area() { ….
方法的名字必须符合标识符规定。在给方法起名字时应遵守以下习惯:名字如果使用拉丁字母,首写字母使用小写。如果由多个单词组成,从第2个单词开始的其它单词的首写字母使用大写。例如 float getTrangleArea() void setCircleRadius(double radius) 等。 方法声明之后的一对大括号“{”、“}”以及之间的内容称作方法的方法体。 类中的方法必须要有方法体,如果方法的类型是void类型,方法体中也可以不书写任何语句。
2.方法体的构成 方法体的内容包括变量的定义和合法的Java语句,在方法体中声明的变量以及方法的参数称作局部变量,局部变量仅仅在该方法内有效。方法的参数在整个方法内有效,方法内定义的局部变量从它定义的位置之后开始有效。写一个方法和C语言中写一个函数完全类似,只不过在这里称作方法。局部变量的名字必须符合标识符规定,遵守习惯:名字如果使用拉丁字母,首写字母使用小写。如果由多个单词组成,从第2个单词开始的其它单词的首写字母使用大写。
A类中的max方法和getMaxSqrt方法是类方法;sum和min方法是实例方法。 3.实例方法与类方法 除构造方法外,其他的方法可分为实例方法或类方法。方法声明中用关键字static修饰的称作类方法或静态方法,不用static修饰的称作实例方法。一个类中的方法可以互相调用:实例方法可以调用该类中实例方法或类方法;类方法只能调用该类的类方法,不能调用实例方法;如: A类中的max方法和getMaxSqrt方法是类方法;sum和min方法是实例方法。
实例方法可以操作成员变量,无论是实例变量或类变量;而类方法只能操作类变量不能操作实例变量,也就是说类方法中不能有操作实例变量的语句。二者为何有着这样的区别呢? (1)实例方法必须通过对象来调用 (2)类方法可以通过类名调用 无论类方法或实例方法,当被调用执行时,方法中的局部变量才被分配内存空间,方法调用完毕,局部变量即刻释放所占的内存。 下面的例子4,通过类名调用类方法。
4.参数传值 当方法被调用时,如果方法有参数,参数必须要实例化,即参数变量必须有具体的值。在Java中,方法的所有参数都是“传值”的,也就是说,方法中参数变量的值是调用者指定的值的拷贝。如果向方法的int型参数x传递一个int值,那么参数x得到的值是传递值的拷贝。方法如果改变参数的值,不会影响向参数“传值”的变量的值。 (1)基本数据类型参数的传值 下面的例子5中,向一个方法的基本型参数传值。效果如图4.11
(2)引用类型参数的传值 Java的引用型数据包括我们以前学习过的对象、数组以及后面将要学习的接口。当参数是引用类型时,“传值”传递的是变量的引用而不是变量所引用的实体。
传值 实体 引用 引用类型参数 引用 引用类型变量 图4.10 引用类型参数的传值
如果改变参数变量所引用的实体,就会导致原变量的实体发生同样的变化,因为,两个引用型变量如果具有同样的引用,就会用同样的实体。但是,改变参数的引用不会影响向其传值的变量的引用。 下面的例子6向一个方法的引用型参数传值。效果如图4.13
注意在上述例子6中,tom调用方法f把对象jerry的引用“传值”给参数a后,对象jerry和对象a就具有同样的成员变量,即同样实体。因此,jerry和a就具有同样的功能,也就是说a调用方法产生的行为和jerry调用同一方法产生的行为完全相同。当对象a执行 a=null; 后,a就不再有任何实体,变成一个空对象,如果再执行: a.setLeg(100);就会引起NullPointerExcetion异常。但是,jerry的引用没有发生任何变化,它依然引用着原来的实体,仍然可以调用方法产生行为。 在下面的例子7中,“Cone”类在创建对象时,将一个“Circle”对象的引用“传值”给“Cone”对象的“bottom”。效果如图4.14
返回
4.8 方法重载 方法重载是指一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同,即或者是参数的个数不同,或者是参数的类型不同。方法的返回类型和参数的名字不参与比较,也就是说,如果两个方法的名字相同,即使类型不同,也必须保证参数不同。 下面例4-8 Area类中getArea方法是一个重载方法。效果如图4.15
返回
4.9 this 关键字 1.在构造方法中使用this this关键字可以出现在类的构造方法中,代表使用该构造方法所创建的对象。 this是Java的一个关键字,可以出现在实例方法和构造方法中,但不可以出现在类方法中。 1.在构造方法中使用this this关键字可以出现在类的构造方法中,代表使用该构造方法所创建的对象。 下述例子9中的构造方法中出现了this,表示该对象在构造自己时调用了方法cry()。 2.在实例方法中使用this this关键字可以出现在类的实例方法中,代表使用该方法的当前对象。
我们已经知道,实例方法可以操作成员变量。实际上,当成员变量在实例方法中出现时,默认的格式是: this.成员变量; 意思是当前对象的成员变量,如: class A { int x; void f( ) { this.x = 100; }
在上述A类中的实例方法f中出现了this,this就代表使用f的当前对象。所以,this 在上述A类中的实例方法f中出现了this,this就代表使用f的当前对象。所以,this.x就表示当前对象的变量x,当对象调用方法f时,将100赋给该对象的变量x。因此,当一个对象调用方法时,方法中的成员变量就是指分配给该对象的成员变量。因此,通常情况下,可以省略成员变量名字前面的“this.”。 我们知道类的实例方法可以调用类的其它方法,调用的默认格式是: this.方法;
如:在上述B类中的方法f中出现了this,this代表使用方法f的当前对象,所以,方法f的方法体中this 如:在上述B类中的方法f中出现了this,this代表使用方法f的当前对象,所以,方法f的方法体中this.g()就是当前对象调用方法g,也就是说,当某个对象调用方法f过程中,又调用了方法g。由于这种逻辑关系非常明确,一个方法调用另一个方法时可以省略方法名字前面的“this.”。 3.类方法中不可以使用this this不能出现在类方法中,这是因为,类方法可以通过类名直接调用,这时,可能还没有任何对象诞生。
如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。如: 4.使用this区分成员变量和局部变量 我们已经知道,成员变量在整个类内有效,局部变量仅在方法内有效。在方法体中声明的变量以及方法的参数称作局部变量,方法的参数在整个方法内有效,方法内定义的局部变量从它定义的位置之后开始有效。 如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。如: 这时如果想在该方法内使用成员变量,成员变量前面的“this.”就不可以省略,如: this.sideA、this.sideB、this.sideC就分别表示当前对象的成员变量sideA、sideB、sideC。 返回
4.10 包 通过关键字package声明包语句。package 语句作为Java源文件的第一条语句,指明该源文件定义的类所在的包。package语句的一般格式为: package 包名; 如果源程序中省略了package语句,源文件中所定义命名的类被隐含地认为是无名包的一部分,即源文件中定义命名的类在同一个包中,但该包没有名字。 包名可以是一个合法的标识符,也可以是若干个标识符加“.”分割而成,如: package sunrise; package sun.com.cn;
c:\1000\tom\jiafei\javac 源文件 程序如果使用了包语句,例如: package tom.jiafei; 那么你的目录结构必须包含有如下的结构 …\tom\jiafei 比如 c:\1000\tom\jiafei 并且要将源文件编译后得到的全部字节码文件拷贝到目录c:\1000\tom\jiafei中,如果你事先将源文件保存到c:\1000\tom\jiafei中,然后编译源文件,那么生成的字节码文件就直接保存到当前目录中了,如: c:\1000\tom\jiafei\javac 源文件 我们将下述例子10的源文件保存到c:\1000\tom\jiafei。效果如图4.17
然后编译原文件: c:\1000\tom\jiafei\javac Example.java 运行程序时必须到tom\jiafei的上一层目录1000中来运行,如: c:\1000\java tom.jiafei.Example 因为起了包名,类Example的全名已经是:tom.jiafei. Example(就好比大连的全名是:“中国.辽宁.大连”)。 包名应该避免与其他包名冲突。但要做到这一点似乎很困难,如果你的包需要在全世界是唯一的,Sun公司建议大家使用自己所在公司的Internet域名倒置后做包名,例如,将域名“sina.com.cn”的倒置“cn.com.sina”做包名。
2.使用参数“–d”编译源文件 javac 可以使用参数-d指定生成的字节码文件所在的目录。如果不使用参数-d,javac在当前目录生成字节码文件。 如果源文件没有包名,使用参数-d可以将字节码文件存放到你指定的有效目录中,例如: javac –d F:\tsinghua\1000 MyFile.java 将源文件MyFile.java生成的全部字节码文件存放到F:\tsinghua\1000。 如果源文件使用包语句声明了包名,使用参数-d时要格外小心。假设源文件的包名是tom.jiafei,保存在在D:\2000中,
下述编译命令: D:\2000\javac –d F:\tsinghua\1000 MyFile.java 会在F:\tsinghua\1000目录下新建子目录结构tom\jiafe并将字节码文件存放到F:\ tsinghua\1000\tom\jiafei中。 而下述编译命令: D:\2000\javac –d . MyFile.java 会在当前目录2000下新建子目录结构tom\jiafei,并将字节码文件存放到D:\2000\tom\jiafei中。 返回
4.11 import 语句 使用import 语句可以引入包中的类。在编写源文件时,除了自己编写类外,我们经常需要使用Java提供的许多类,这些类可能在不同的包中。在学习Java语言时,使用已经存在的类,避免一切从头做起,这是面向对象编程的一个重要方面。 1 .使用类库中的类 为了能使用Java提供给我们的类,我们可以使用import语句来引入包中类。在一个Java源程序中可以有多个import语句,它们必须写在package语句(假如有package语句的话)和源文件中类的定义之间。
Java为我们提供了大约130多个包,如: java.applet 包含所有的实现Java applet的类 java.awt 包含抽象窗口工具集中的图形、文本、窗口GUI类 java.awt.image 包含抽象窗口工具集中的图像处理类 java.lang 包含所有的基本语言类 java.io 包含所有的输入输出类 java.net 包含所有实现网络功能的类 java.util 包含有用的数据类型类
如果使用import语句引入了整个包中的类,那么可能会增加编译时间。但绝对不会影响程序运行的性能。Java运行平台由所需要的Java类库和虚拟机组成,这些类库被包含在一个jre\lib中的压缩文件rt.jar中,当程序执行时,Java运行平台从类库中加载程序真正使用的类字节码到内存。 下面的例子11使用了java.util包中的Date类,用来显示本机的当前时间。
2.使用自定义包中的类 我们也可以使用import 语句引入自定义包中的类。如: import tom.jiafei.*; 我们也可以对单独的一个类进行编译,生成字节码文件然后供其它类使用。 以下的源文件SquareEquation.java只有一个类组成,这个类可以被其它的程序引入使用,该源文件的包名是tom.jiafei。 为了使程序能使用tom.jiafei包中的类,我们必须在 classpath中指明我们包的位置,假设tom.jiafei的位置是:c:\2000,即在c:\2000下有子目录tom\jiafei。更新classpath的设置,在命令行执行如下命令: set classpath=E:\jdk1.5\jre\lib\rt.jar;.;c:\2000
也可以将上述命令添加到Classpath值中。在Windows2000系统中,右击“我的电脑”,弹出快捷菜单,然后选择“属性”命令,弹出“系统特性”对话框,再单击该对话框中的高级选项,然后单击“环境变量”按钮。对于Win9x系统可以将上述命令写到autoexec.bat文件中。 将下述源文件SquareEquation.java编译得到的字节码文件拷贝到D:\ch4\tom\jiafei中。下面的例子12的源文件保存在 D:\Ch4目录中,并用import 语句引入包tom.jiafei中的SquareEquation类。
3.使用无名包中的类 我们也可以使用无名包中的类。假如上述SquareEquation.java源文件中没有使用包语句,如果一个程序使用SquareEquation类,可以将该类的字节码文件存放在当前程序所在的目录中。 编写一个有价值的类是令人高兴的事情,你可以将这样的类打包,形成有价值的“软件产品”,供其他软件开发者使用。 4.避免类名混淆 Java运行环境总是先到程序所在目录中寻找程序所使用的类,然后加载到内存。
如果在当前目录没有发现所需要的类,就到import语句所指的包中查找。如果在当前目录中寻找到了要加载的类,那么程序就不会再加载import语句引入的同名类。 返回
4.12 访问权限 1.私有变量和私有方法 用关键字private修饰的成员变量和方法被称为私有变量和私有方法。 4.12 访问权限 类有2种重要的成员:成员变量和方法。类创建的对象可以通过“.”运算符访问分配给自己的变量,也可以通过“.”运算符调用类中的实例方法和类方法。 类在定义声明成员变量和方法时,可以用关键字private、protected和public来说明成员变量和方法的访问权限,使得对象访问自己的变量和使用方法受到一定的限制。 1.私有变量和私有方法 用关键字private修饰的成员变量和方法被称为私有变量和私有方法。 对于私有成员变量或方法,只有在本类中创建该类的对象时,这个对象才能访问自己的私有成员变量和类中的私有方法,如例子13,例子14所示。效果如图4.21
用某个类在另外的一个类中创建对象后,如果不希望该对象直接访问自己的变量(即通过“ 用某个类在另外的一个类中创建对象后,如果不希望该对象直接访问自己的变量(即通过“.”运算符来操作自己的成员变量),就应将该变量访问权限设置为private。 面向对象编程提倡对象应当调用方法来改变自己的属性,我们应当提供操作数据的方法,这些方法可以经过精心设计,使得对数据的操作更加合理。
用public修饰的成员变量和方法被称为共有变量和共有方法,如: 2.共有变量和共有方法 用public修饰的成员变量和方法被称为共有变量和共有方法,如: class A { public float weight; //weight被修饰为public的float型变量。 public float f(float a,float b) { //方法 f是public方法。 }
class B { void g() { A a = new A(); a.weight = 23f; //合法 当我们在任何一个类中用类A 创建了一个对象后,该 对象能访问自己的public变量和类中的public方法。如: class B { void g() { A a = new A(); a.weight = 23f; //合法 a.f(3,4); //合法 }
3.友好变量和友好方法 不用private、public 、protected修饰符的成员变量和方法被称为友好变量和友好方法,如: class A { float weight; //weight是友好变量 float f(float a,float b) { // f是友好方法 }
假如B与A是同一个包中的类,那么,下述B类中的a.weight、a.f(3,4)都是合法的。 class B { void g() { A cat = new A(); a.weight = 23f; //合法 a.f(3,4); //合法 }
处在同一包中的类的对象可以访问该包中其他类的对象的友好变量与友好方法。
4.受保护的成员变量和方法 用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法,如: class A { protected float weight; //weight被修饰为public变量。 protected float f(float a,float b) { //f是public方法。 … }
class B { void g() { Tom a = new Tom(); a.weight=23f; //合法 假如B与A是同一个包中的类,那么,B类中的a.weight、a.f(3,4)都是合法的。 class B { void g() { Tom a = new Tom(); a.weight=23f; //合法 a.f(3,4); //合法 }
5.public类与友好类 类声明时,如果关键字class前面加上public关键字,就称这样的是一个public类,不能用protected和private修饰类。如: public class A {… … } 可以在任何另外一个类中,使用public类创建对象。如果一个类不加public修饰,这样的类被称为友好类。另外一个类使用友好类创建对象时,要保证它们在同一个包中。如: class A { … … }
6.关于构造方法 private、public 、protected修饰符的意义也同样适合于构造方法。如果一个类没有明确地声明构造方法,那么public类的默认构造方法是public的,友好类的默认构造方法是友好的。需要注意的是,如果一个public类定义声明的构造方法中没有public的,那么在另外一个类中使用该类创建对象时,使用的构造方法就不是public的,创建对象就受到一定的限制。
假设对象a是类A创建的,对象对成员的访问权限总结如下: 对象a的位置 Private 成员 友好的 protected public √ × 返回
4.13 对象的组合 一个类可以把对象作为自己的成员变量,如果用这样的类创建对象,那么该对象中就会有其它对象,也就是说该对象将其他对象作为自己的组成部分(这就是人们常说的 Has-A),或者说该对象是由几个对象组合而成 。 例子15
4.14 基本类型数据的类包装 基本数据类型 包装类 包装类的创建 值的获取 byte Byte Byte(byte num) 4.14 基本类型数据的类包装 基本数据类型 包装类 包装类的创建 值的获取 byte Byte Byte(byte num) byteValue () int Integer Integer(int num) intValue() short Short Short(short num) shortValue () long Long Long(long num) longValue () float Float Float (float num) floatValue() double Double Double (double num) doubleValue() char Character Character (char c) charValue()
3.Character类中的一些常用类方法:
l public static boolean isDigit(char ch) 如果ch是数字字符方法返回 true,否则返回false。 l public static boolean isLetter(char ch) 如果ch是字母方法返回 true,否则返回false。 l public static boolean isLetterOrDigit(char ch) 如果ch是数字字符或字母方法返回 true,否则返回false。 l public static boolean isLowerCase(char ch) 如果ch是小写字母方法返回 true,否则返回false。
l public static boolean isUpperCase(char ch) 如果ch是大写字母方法返回 true,否则返回false。 l public static char toLowerCase(char ch) 返回ch的小写形式。 l public static char toUpperCase(char ch) 返回ch的大写形式。 l public static boolean isSpaceChar(char ch) 如果ch是空格返回true。
在下面的例子16中,将一个字符数组中的小写字母变成大写字母,并将大写字母变成小写字母。
返回
4.13 反编译和文档生成器 使用SDK提供的反编译器:javap.exe可以将字节码反编译为源码,查看源码类中的public方法名字和public成员变量的名字,例如: c:\>javap java.awt.Button 将列出Button中的public方法和public成员变量。下列命令 c:\> javap –private java.awt.Button 将列出Button中的全部方法和成员变量。
使用SDK提供的javadoc.exe可以制作源文件类结构的html格式文档。 假设D:\test有源文件:Example.java,用javadoc生成Example.java的html格式文挡: javadoc Example.java 这时在文件夹test中将生成若干个html文挡,查看这些文档可以知道源文件中类的组成结构,如类中的方法和成员变量。 使用javadoc时,也可以使用-d参数指定生成文挡所在的目录,例如, javadoc –d F:\gxy\book Example.java <例子> 返回
JAR文件 Java应用程序在运行时,需要将使用到的字节码文件加载到内存,因此对字节码文件所在的位置就有特殊的要求。主要有以下四种情形: 1. 使用当前应用程序所在目录中没有包名的类; 2. 使用java运行环境中类库中的类; 3. 使用应用程序当前目录的子孙目录中的类; 4. 使用Java运行环境扩展中的类。
JAR(Java Archive,Java档案),是一种具有特殊内部结构的标准压缩文件。可以用winrar等压缩软件打开JAR文件。 JAR文件可以包含任何内容,如类文件、要使用的图像文件或其他数据、程序源代码等等。JAR内部的结构就象标准目录设置,每个文件都有位置和目录,就象磁盘中的目录结构一样。 使用jar.exe可以将一些类的字节码文件压缩打包成一个“.jar”文件。 如: jar cf mylib.jar * ---将当前目录中的所有文件打包到mylib.jar 中。 <例子 ch4\jar> 返回
对象的组合 一个类的成员变量可以是Java允许的任何数据类型,包括对象。 一个对象可以将另外一个对象作为自己的组成部分。 <例子 ch4\例子15> 返回 对象a 对象b 对象c(a与b的组合)
感谢您使用weleve产品! 1、本课件发布于2011年06月20日,由全国专业人才教育网制作,未标明原创的课件均从网络收集或是会员上传,版权归原作者所有,请大家尊重作者的劳动成果,并积极上传自己的作品与大家一起分享交流。 2、在使用本产品过程中,如有问题,欢迎联系专业人才教育网客服: Email:harb2006@163.com QQ:1330691858 亢龙有悔 全国专业人才教育网: www.weleve.com