Presentation is loading. Please wait.

Presentation is loading. Please wait.

本章导读 类声明和类体及其构成 第4章 类与对象 本章导读 import语句 构造方法与对象的创建 访问权限 对象的引用与实体

Similar presentations


Presentation on theme: "本章导读 类声明和类体及其构成 第4章 类与对象 本章导读 import语句 构造方法与对象的创建 访问权限 对象的引用与实体"— Presentation transcript:

1 本章导读 类声明和类体及其构成 第4章 类与对象 本章导读 import语句 构造方法与对象的创建 访问权限 对象的引用与实体
第4章 类与对象 本章导读 类声明和类体及其构成 构造方法与对象的创建 对象的引用与实体 成员变量、方法和方法重载 关键字this 本章导读 import语句 访问权限 对象的组合 基本类型数据的类包装 反编译和文档生成器 JAR文件的使用 2017/2/24 1

2 4.1 面向对象编程 1. 面向对象编程的三个特性 (1)封装:面向对象编程核心思想之一就是将数据和对数据的操作封装在一起。通过抽象,即从具体的实例中抽取共同的性质形成一般的概念,比如类的概念。 人们经常谈到的机动车类就是从具体的实例中抽取共同的属性和功能形成的一个概念,那么一个具体的轿车就是机动车类的一个实例,即对象。 一个对象将自己的数据和对这些数据的操作合理有效地封装在一起,例如,每辆轿车调用“加速”、“减速”改变的都是自己的运行速度。 (2)继承 继承体现了一种先进的编程模式。子类可以继承父类的属性和功能,即继承了父类所具有的数据和数据上的操作,同时又可以增添子类独有的数据和数据上的操。 (3)多态 多态是面向对象编程的又一重要特征。有两种意义的多态,一种是操作名称的多态,即有多个操作具有相同的名字,但这些操作所接收的消息类型必须不同。另一种多态是和继承有关的多态,是指同一个操作被不同类型对象调用时可能产生不同的行为。 2017/2/24 2

3 能否将和圆有关的数据以及计算圆面积的代码进行封装,使得需要计算圆面积的Java应用程序的主类无需编写计算面积的代码就可以计算出圆的面积呢?
2.提出一个简单的问题 例题4-1能输出圆的面积 ,效果如图4-1所示。 通过运行上述Java应用程序注意到这样一个事实:如果其他Java应用程序也想计算圆的面积,同样需要知道计算圆面积的算法,即也需要编写和这里同样多的代码。现在提出如下问题: 能否将和圆有关的数据以及计算圆面积的代码进行封装,使得需要计算圆面积的Java应用程序的主类无需编写计算面积的代码就可以计算出圆的面积呢? 2017/2/24 3

4 3.简单的Circle类 面向对象的一个重要思想就是通过抽象得到类,即将某些数据以及针对这些数据上的操作封装在一个类中,也就是说,抽象的关键点有两点一是数据,二是数据上的操作。 我们对所观察的圆做如下抽象: ☃圆具有半径之属性。 ☃可以使用半径计算出圆的面积。 现在根据如上的抽象,编写出如下的Circle类。 class Circle { double radius; //圆的半径 double getArea() { //计算面积的方法 double area=3.14*radius*radius; return area; } (1)类声明:上述代码第一行中的class Circle称作类声明,Circle是类名。 (2)类体:类声明之后的一对大括号“{”,“}”以及它们之间的内容称作类体,大括号之间的内容称作类体的内容。 2017/2/24 4

5 4.使用Circle类创建对象 在例子4-2的主类中使用Circle类创建对象,该对象可以完成计算圆面积的任务(主类不必知道计算圆面积的算法) 。 由于类也是一种数据类型,因此可以使用类来声明一个变量,那么,在Java语言中,用类声明的变量就称之为一个对象。 用Circle声明一个名字为circle的对象的代码如下: Circle circle; 为Circle类声明的circle对象分配变量的代码如下: circle = new Circle(); 对象通过使用“.”运算符操作自己的变量和调用方法。 对象操作自己的变量的的格式为:对象.变量; 例如,circle.radius=100; 调用方法的格式为: 对象.方法; 例如,circle.getArea(); 在例子4-2中的Example4_2.java及编译得到的Circle类的字节码文件Circle.class保存在C:\ch4中 ,程序运行效果如图4.2。 2017/2/24 5

6 5. Java应用的程序的基本结构 一个Java应用程序是由若干个类所构成,但必须有一个主类,即含有main方法的类,Java应用程序总是从主类的main方法开始执行。在编写一个Java应用程序时,可以编写若干个Java源文件,每个源文件编译后产生每个类的字节码文件。因此,经常需要进行如下的操作。 ▲将应用程序涉及的Java源文件保存在相同的目录中,分别编译通过,得到Java应用程序所需要的字节码文件。 ▲运行主类 注:如果应用程序的主类的源文件和其他的源文件在同一目录中,也可以只编译主类的源文件,Java系统会自动地先编译主类需要的其它源文件。 Java程序以类为“基本单位”,即一个Java程序就是由若干个类所构成。一个Java程序可以将它使用的各个类分别存放在不同的源文件中,也可以将它使用的类存放在一个源文件中。一个源文件中的类可以被多个Java程序使用,从编译角度看,每个源文件都是一个独立的编译单位,当程序需要修改某个类时,只需要重新编译该类所在的源文件即可,不必重新编译其他类所在的源文件,这非常有利于系统的维护。 2017/2/24 6

7 4.2 类声明和类体 类是组成Java程序的基本要素。类封装了一类对象的状态和方法。类是用来定义对象的模板。可以用类创建对象,当使用一个类创建了一个对象时,我们也说给出了这个类的一个实例。 在语法上,类由两部分构成:类声明和类体。基本格式为: class 类名 { 类体的内容…… } class是关键字,用来定义类。 “class 类名”是类的声明部分,类名必须是合法的Java标识符。 两个大括号“{”、“}”以及之间的内容称作类体。 例如 class 机动车 { … … 2017/2/24 7

8 类名的命名习惯 习惯上,类名的第一个字母大写,但这不是必须的。
类的名字不能是Java中的关键字,要符合标识符规定,即名字可以由字母、下划线、数字或美元符号组成,并且第一个字符不能是数字。但给类命名时,最好遵守下列习惯: (1)如果类名使用英文字母,那么名字的首字母使用大写字母,如Hello、Time、,People等。 (2)类名最好容易识别、见名知意。当类名由几个“单词”复合而成时,每个单词的首写字母使用大写,如BeijingTime、AmericanGame、HelloChina等。 2017/2/24 8

9 写类的目的是为了描述一类事物共有的属性和功能,即将数据和对数据的操作封装在一起,这一过程由类体来实现。类体内容可以有两种类型的成员:
4.3 类体的构成 写类的目的是为了描述一类事物共有的属性和功能,即将数据和对数据的操作封装在一起,这一过程由类体来实现。类体内容可以有两种类型的成员: 1.成员变量:通过变量声明定义的变量,称作成员变量或域,用来刻画类创建的对象的属性。 2.方法:方法是类体的重要成员之一。其中的构造方法是具有特殊地位的方法,供类创建对象时使用,用来给出类所创建的对象的初始状态,另一类方法,可以由类所创建的对象调用,对象调用这些方法操作成员变量形成一定的算法,体现对象具有某种功能。 2017/2/24 9

10 类名为“机动车”的类 类体内容的变量定义部分定义了2个float类型的变量:“weight”、“height”和一个int型变量“speed”;方法定义部分定义了3个方法:“changSpeed”、“getWeight”和“getHeight”。 class 机动车{ int speed; //变量定义部分 float weight,height; //变量定义部分 void changSpeed(int newSpeed){ //方法定义 speed=newSpeed; } float getWeight(){ //方法定义 return weight; float getHeight(){ //方法定义 return height; 2017/2/24 10

11 成员变量的类型可以是Java中的任何一种数据类型,包括前面学习过的基本类型:整型、浮点型、字符型、数组以及后面要学习的对象及接口。
关于成员变量 成员变量的类型可以是Java中的任何一种数据类型,包括前面学习过的基本类型:整型、浮点型、字符型、数组以及后面要学习的对象及接口。 成员变量在整个类内都有效,与它在类体中书写的先后位置无关(“机动车” )。 在定义类的成员变量时可以同时赋予初值,表明类所创建的对象的初始状态。 注意 : 对成员变量的操作只能放在方法中,方法可以对成员变量进行操作形成算法,见P41例子。 2017/2/24 11

12 类中有一部分方法称作构造方法,类创建对象时需使用构造方法,以便给类所创建的对象一个合理的初始状态。
4.4 构造方法与对象的创建 类中有一部分方法称作构造方法,类创建对象时需使用构造方法,以便给类所创建的对象一个合理的初始状态。 构造方法是一种特殊方法,它的名字必须与它所在的类的名字完全相同,并且不返回任何数据类型,即它是void型,但void必须省略不写。 Java允许一个类中有若干个构造方法,但这些构造方法的参数必须不同,即或者是参数的个数不同,或者是参数的类型不同。下面的Rect类有两个构造方法: class Rect { double sizdA,siddB; Rect(){ } //无参数构造方法。 Rect(double a,double b) { //有参数构造方法。 sideA=a; sideB=b; } double computerArea(){ return sideA*sideB; double computerGirth(){ return (sizeA+sideB)*2; 2017/2/24 12

13 1.对象的声明 一般格式为: 类的名字 对象名字; 如: Rect rectangleOne;
一般格式为: 类的名字 对象名字; 如: Rect rectangleOne; 声明对象变量rectangleOne后,rectangleOne的内存中还没有存放数据,也就是说该对象还没有“引用”任何实体,我们称这时的rectangleOne是一个空对象。 2017/2/24 13

14 2.为声明的对象分配成员变量 使用new运算符和类的构造方法为声明的对象分配成员变量,如果类中没有构造方法,系统会调用默认的构造方法(默认的构造方法是无参数的,你一定还记得构造方法的名字必须和类名相同这一规定),上述的Rect类提供了两个构造方法,下面都是合法的创建对象的语句: rectangleOne =new Rect(); rectangleOne =new Rect(10,20); 此代码会实现下述两件事: ( 1)为成员变量分配内存空间,然后执行构造方法中的语句 。 ( 2 )给出一个信息,已确保这些成员变量是属于对象 rectangleOne的 。 对象的声明和分配成员变量两个步骤可以用一个等价的步骤完成,如 Rect rectangleOne =new Rect(10,20); 2017/2/24 14

15 3.创建多个不同的对象 一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的内存空间,因此,改变其中一个对象的状态不会影响其它对象的状态。例如,我们使用前面的Rect类创建两个对象: Rect rectangleOne,rectangleTwo; rectangleOne =new Rect(10,20); rectangleTwo =new Rect(33,66); 当创建对象rectangleOne时,Rect类中的成员变量sizeA、sizeB被分配内存空间,并返回一个引用给ectangleOne; 当再创建一个对象rectangleTwo时,Rect类中的成员变量sizeA、sizeB再一次被分配内存空间,并返回一个 引用给rectangleTwo 。内存模型如图4-5所示。 2017/2/24 15

16 4.使用对象 对象不仅可以操作自己的变量改变状态,而且还拥有了使用创建它的那个类中的方法的能力,对象通过使用这些方法可以产生一定的行为。
通过使用运算符“.”,对象可以实现对自己的变量访问 和方法的调用。 (1)对象操作自己的变量(对象的属性) (2)对象调用类中的方法(对象的功能) (3)体现封装 当对象调用方法时,方法中出现的成员变量就是指该对象的成员变量。 下面例子4-3中,“Lader”类创建了2个对象laderOne,laderTwo.效果如图4-6所示. 2017/2/24 16

17 4.5 对象的引用与实体 我们已经知道,当用类创建一个对象时,成员变量被分配内存空间,这些内存空间称做该对象的实体或变量,而对象中存放着引用,以确保这些变量由该对象操作使用。因此,如果两个对象有相同的引用,那么就具有同样的实体。 假如使用例4-3中类Lader的构造方法创建了两个对象t1和t2(内存示意如图4.7所示): t1=new Lader(11,22,33); t2=new Lader(6,12,18); 若在程序中使用了下述赋值语句: t1=t2; 它把t2的引用赋给了t1,那么t1和t2引用的实体就是一样的了。系统将取消原来分配给t1的实体,即分配给t1的成员变量的内存将被释放,内存示意如图4.8所示. 2017/2/24 17

18 4.6 成员变量 1.类变量和实例变量 用关键字static修饰的成员变量称作静态变量或类变量, 而没有使用static修饰的成员变量称作实例变量。例如,下述A类中,x是实例变量,而y是类变量。 class A { float x; static int y; } 类变量是与类相关联的数据变量,也就是说,类变量是和该类所创建的所有对象相关联的变量,改变其中一个对象的这个类变量就同时改变了其它对象的这个类变量。因此,类变量不仅可以通过某个对象访问也可以直接通过类名访问。 实例变量仅仅是和相应的对象关联的变量,也就是说,不同对象的实例变量互不相同,即分配不同的内存空间,改变其中一个对象的实例变量不会影响其它对象的这个实例变量。实例变量必须通过对象访问。 下面例子4-4中,两个“ Lader”对象共享bottom。效果如图4.9 2017/2/24 18

19 图4.9 例子4-4效果图 图4.10 对象共享类变量 2017/2/24 19

20 如果一个成员变量修饰为final,就是常量,常量的名字习惯用大写字母,例如: final int MAX_SIZE;
2.符号常量 如果一个成员变量修饰为final,就是常量,常量的名字习惯用大写字母,例如: final int MAX_SIZE; final修饰的成员变量不占用内存,这意味着在声明final成员变量时,必须要初始化。对于final修饰的成员变量,对象可以操作使用,但不能做更改操作。下面的例子4-5给出了常量的用法。 2017/2/24 20

21 4.7 方法 我们已经知道,类体内容可以有2种类型的成员:成员变量和方法。其中一部分方法称作构造方法,供类创建对象时使用,用来给出类所创建的对象的初始状态。另一部分方法可分为实例方法和类方法,类所创建的对象可以调用这些方法形成一定的算法,体现对象具有某种功能。当对象调用方法时,方法中出现的成员变量就是指分配给该对象的成员变量。对象不可以调用构造方法,构造方法是专门用来创建对象的。 方法的定义包括两部分:方法声明和方法体。一般格式为: 方法声明部分{ 方法体的内容 } 2017/2/24 21

22 1.方法声明和方法体 最基本的方法声明包括方法名和方法的返回类型,返回类型也简称作方法的类型。如:
float area(){ …. } 方法的名字必须符合标识符规定。在给方法起名字时应遵守以下习惯:名字如果使用拉丁字母,首写字母使用小写。如果由多个单词组成,从第2个单词开始的其它单词的首写字母使用大写。例如 float getTrangleArea() void setCircleRadius(double radius) 等。方法声明之后的一对大括号“{”、“}”以及之间的内容称作方法的方法体。类中的方法必须要有方法体,如果方法的类型是void类型,方法体中也可以不书写任何语句。 2017/2/24 22

23 方法体的内容包括变量的定义和合法的Java语句。
2.方法体的构成 方法体的内容包括变量的定义和合法的Java语句。 在方法体中声明的变量以及方法的参数称作局部变量,局部变量仅仅在该方法内有效。方法的参数在整个方法内有效,方法内定义的局部变量从它定义的位置之后开始有效。 局部变量的名字必须符合标识符规定,遵守习惯:名字如果使用拉丁字母,首写字母使用小写。如果由多个单词组成,从第2个单词开始的其它单词的首写字母使用大写。 2017/2/24 23

24 3.实例方法与类方法 A类中的max方法和getMaxSqrt方法是类方法;sum和min方法是实例方法。
除构造方法外,其他的方法可分为实例方法或类方法。方法声明中用关键字static修饰的称作类方法或静态方法,不用static修饰的称作实例方法。一个类中的方法可以互相调用:实例方法可以调用该类中实例方法或类方法;类方法只能调用该类的类方法,不能调用实例方法;例如: (P49例子.txt) A类中的max方法和getMaxSqrt方法是类方法;sum和min方法是实例方法。 实例方法可以操作成员变量,无论是实例变量或类变量;而也就是说类方法中不能有操作实例变量的语句。二者为何类方法只能操作类变量不能操作实例变量,有着这样的区别呢? (1)实例方法必须通过对象来调用 (2)类方法可以通过类名调用 无论类方法或实例方法,当被调用执行时,方法中的局部变量才被分配内存空间,方法调用完毕,局部变量即刻释放所占的内存。 下面的例子4-6,通过类名调用类方法。 2017/2/24 24

25 4.参数传值 当方法被调用时,如果方法有参数(形参),参数必须要实例化,即参数变量必须有具体的值(实参)。在Java中,方法的所有参数都是“传值”的,也就是说,方法中参数变量(形参)的值是调用者指定的值(实参)的拷贝。如果向方法的int型参数x传递一个int值,那么参数x得到的值是传递值的拷贝。方法如果改变参数的值,不会影响向参数“传值”的变量的值。 (1)基本数据类型参数的传值 对于基本数据类型的参数,向该参数传递的值的级别不可以高于该参数的级别。 下面的例子7中,向一个方法的基本型参数传值。效果如图4.11 2017/2/24 25

26 下面的例子8向一个方法的引用型参数传值。效果如图4.13
(2)引用类型参数的传值 Java的引用型数据包括我们以前学习过的对象、数组以及后面将要学习的接口。当参数是引用类型时,“传值”传递的是变量的引用而不是变量所引用的实体。 图4-12 引用类型参数的传值 如果改变参数变量(形参)所引用的实体,就会导致原变量(实参)的实体发生同样的变化,因为,两个引用型变量如果具有同样的引用,就会用同样的实体。但是,改变参数(形参)的引用不会影响向其传值的变量的引用。 下面的例子8向一个方法的引用型参数传值。效果如图4.13 2017/2/24 26

27 例题4-9 在上述例4-8中,cat调用方法f把对象jerry的引用“传值”给参数mouse后,对象jerry和对象mouse就具有同样的成员变量,即同样的实体。因此,jerry和mouse就具有同样的功能,即mouse调用方法产生的行为和jerry调用同一方法产生的行为完全相同。当对象mouse执行 mouse=null; 后,mouse就不再有任何实体,变成一个空对象,如果再执行 mouse.setLeg(100); 就会引起NullPointerExcetion异常。 但是,jerry的引用没有发生任何变化,它依然引用着原来的实体,仍然可以调用方法产生行为。 在下面的例4-9中(效果如图4.14所示),类Cone在创建对象时,将一个Circle对象的引用“传值”给Cone对象的bottom。 2017/2/24 27

28 例子4-9效果图 2017/2/24 28

29 4.8 方法重载 方法重载是指一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同,即或者是参数的个数不同,或者是参数的类型不同。方法的返回类型和参数的名字不参与比较,也就是说,如果两个方法的名字相同,即使返回值类型不同,也必须保证参数不同。 方法重载是多态性的一种。所谓功能多态性(静态多态),是指可以向方法传递不同的消息,以便让对象根据相应的消息来产生一定的行为。对象的功能通过类中的方法来体现,那么功能的多态性就是方法的重载。 下面例4-10 Area类中getArea方法是一个重载方法。效果如图4.15 2017/2/24 29

30 4.9 this 关键字 this是Java的一个关键字,是指向自身对象的引用。可以出现在实例方法和构造方法中,但不可以出现在类方法中。
下述例子11中的构造方法中出现了this,表示该对象在构造自己时调用了方法cry()。 2017/2/24 30

31 this关键字可以出现在类的实例方法中,代表使用该方法的当前对象。
意思是当前对象的成员变量,如: 在A类中的实例方法f中出现了this,this就代表使用f的当前对象。所以,this.x就表示当前对象的变量x,当对象调用方法f时,将100赋给该对象的变量x。 当一个对象调用方法时,方法中的成员变量就是指分配给该对象的成员变量。因此,通常情况下,可以省略成员变量名字前面的“this.”。 class A { int x; void f() { this.x=100; } 2017/2/24 31

32 我们知道类的实例方法可以调用类的其它方法,调用的默认格式是 this.方法;
在类B中的方法f中出现了this,this代表使用方法f的当前对象,所以方法f的方法体中this.g()就是当前对象调用方法g。 就是说,当某个对象调用方法f过程中,又调用了方法g。由于这种逻辑关系非常明确,一个方法调用另一个方法时可以省略方法名字前面的“this.”。 class B{ void f(){ this.g(); //对象调用方法f时又调用了方法g } void g(){ System.out.println("ok"); 2017/2/24 32

33 this不能出现在类方法中,这是因为,类方法可以通过类名直接调用,这时,可能还没有任何对象诞生。
2017/2/24 33

34 我们已经知道,成员变量在整个类内有效,局部变量仅在方法内有效。
4.使用this区分成员变量和局部变量 我们已经知道,成员变量在整个类内有效,局部变量仅在方法内有效。 在方法体中声明的变量以及方法的参数称作局部变量,方法的参数在整个方法内有效,方法内定义的局部变量从它定义的位置之后开始有效。 如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。如: class Tom{ int x=188,y; void f(){ int x=3; y=x; //y得到的值是3,不是188。如果方法f中没有“int x=3;”语句, //y的值将是98 } 2017/2/24 34

35 如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。
4.使用this区分成员变量和局部变量 如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。 这时如果想在该方法内使用成员变量,成员变量前面的“this.”就不可以省略,如: class Tra{ float sideA,sideB,sideC; static int count; void setSide(float sideA,float sideB,float sideC){ this.sideA=sideA; //使用this区分成员变量和局部变量 this.sideB=sideB; //this.sideA、this.sideB、this.sideC就分别表示 this.sideC=sideC; //当前对象的成员变量sideA、sideB、sideC, } static void setCount(int count){ Tra.count=count; //使用类名区分成员变量和局部变量 } // Tra.count就表示所有对象共享的类变量。 2017/2/24 35

36 4.10 包 1.包语句 package sunrise; 包是Java语言中有效管理类的一个机制。
4.10 包 .包语句 包是Java语言中有效管理类的一个机制。 通过关键字package声明包语句。package 语句作为Java源文件的第一条语句,指明该源文件定义的类所在的包。package语句的一般格式为: package 包名; 如果源程序中省略了package语句,源文件中所定义命名的类被隐含地认为是无名包的一部分,即源文件中定义命名的类在同一个包中,但该包没有名字。 包名可以是一个合法的标识符,也可以是若干个标识符加“.”分割而成,如: package sunrise; package sun.com.cn; 2017/2/24 36

37 运行 D:\ch4 \java tom.jiafei. Example4_12
包名与目录结构 程序如果使用了包语句,例如: package tom.jiafei; 那么你的目录结构必须包含有如下的结构 …\tom\jiafei 比如 D:\ch4 \tom\jiafei 并且要将源文件编译后得到的全部字节码文件拷贝到目录D:\ch4 \tom\jiafei中。 例子12的源文件保存到D:\ch4 \tom\jiafei中。 编译源文件 D:\ch4 \tom\jiafei\javac Example4_12.java 运行 D:\ch4 \java tom.jiafei. Example4_12 效果如图4.16 因为起了包名,类Example4_12的全名已经是tom.jiafei.Example4_12(就好比大连的全名是“中国.辽宁.大连”) 2017/2/24 37

38 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中。 2017/2/24 38

39 使用import 语句可以引入包中的类。在编写源文件时,除了自己编写类外,我们经常需要使用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 包含有用的数据类型类 例子13使用了java.util包中的Date类,用来显示本机的当前时间. 2017/2/24 39

40 我们也可以使用import 语句引入自定义包中的类。如:
2.使用自定义包和无名包中的类 我们也可以使用import 语句引入自定义包中的类。如: import tom.jiafei.*; 我们也可以对单独的一个类进行编译,生成字节码文件然后供其它类使用。 (1)如果应用的程序所需要的其它源文件没有包名,那么必须将该源文件编译后得到的字节码文件和应用程序存放在同一目录中。 (2)如果应用的程序所需要的其它源文件有包名,比如tom.jiafei,那么可以将该源文件编译后得到的字节码文件存放到应用程序所在目录的tom\jiafei子目录中,比如应用程序所在目录为d:\ch4,那么在ch4下再建立子目录tom\jiafei,然后将应用程序所需的包名为tom.jiafei的字节码存放到d:\ch4\tom\jiafei中。 2017/2/24 40

41 Classpath的设置 (3)如果应用的程序所需要的其它源文件有包名,比如tom.jiafei,但是没有将该源文件编译后得到的字节码文件存放到应用程序所在目录的tom\jiafei子目录中,而存放在其他目录的tom\jiafei子目录中,比如C:\2000\ tom\jiafei中,那么,就必须在classpath中指明tom.jiafei包的位置。可以在在命令行执行如下命令 set classpath=E:\jdk1.6\jre\lib\rt.jar;.;C:\2000 或将上述命令添加到classpath值中。 将下述源文件SquareEquation.java编译得到的字节码文件拷贝到D:\ch4\tom\jiafei中。 例子14的源文件保存在 D:\Ch4目录中,并用import 语句引入包tom.jiafei中的SquareEquation类。 我们也可使用无名包中的类。若上述SquareEquation.java源文件中没有使用包语句,如果一个程序使用SquareEquation类,可以将该类的字节码文件存放在当前程序所在的目录中。 2017/2/24 41

42 例子4-14效果图 2017/2/24 42

43 3. 避免类名混淆 Java运行环境总是先到程序所在目录中寻找程序所使用的类,然后加载到内存。如果在当前目录没有发现所需要的类,就到import语句所指的包中查找。 当我们在一个源文件使用一个类时,只要不引起混淆,就可以省略该类的包名。但在某些特殊情况下就不能省略包名。 (1)区分无包名和有包名的类 如果一个源文件使用了一个无名包中的类,比如Triangle类,同时又用import语句引入了某个有包名的同名的类,要同时使用tom.jiafei包中的Triangle类和无名包中的Triangle类,就不能省略包名。 Triangle a1=new Triangle (); tom.jiafei.Triangle a2=new tom.jiafei.Triangle (); (2)区分有包名的类 如果一个源文件引入了两个包中同名的类,那么在使用该类时,不允许省略包名。 tom.jiafei.AA rose=new tom.jiafei.AA(); sun.com.AA rose=new sun.com.AA(); 2017/2/24 43

44 4.12 访问权限 类创建的对象可以通过“.”运算符访问分配给自己的变量,也可以通过“.”运算符调用类中的实例方法和类方法。
4.12 访问权限 类创建的对象可以通过“.”运算符访问分配给自己的变量,也可以通过“.”运算符调用类中的实例方法和类方法。 类在定义声明成员变量和方法时,可以用关键字private、protected和public来说明成员变量和方法的访问权限,使得对象访问自己的变量和使用方法受到一定的限制。 需要注意的是,访问权限是指类创建的对象是否可以通过“.”运算符访问分配给自己的变量、是否可以通过“.”运算符调用类中的实例方法和类方法。 而类中的实例方法总是可以操作该类中的实例变量和类变量;类方法总是可以操作该类中的类变量,与访问限制符没有关系。 2017/2/24 44

45 1.私有变量和私有方法 用关键字private修饰的成员变量和方法被称为私有变量和私有方法,例:
class A{ private float weight; //weight被修饰为私有的float类型变量 private float f(float a,float b){ //方法f是私有方法 … … } 对于私有成员变量或方法,只有在本类中创建该类的对象时,这个对象才能访问自己的私有成员变量和类中的私有方法,当在另外一个类中用类A创建了一个对象后,该对象不能访问自己的私有变量和私有方法。例如: class B{ void g(){ A a=new A(); a.weight=23f; //非法 a.f(3f,4f); //非法 如例子15,例子16所示。效果如图4.19 2017/2/24 45

46 当我们在任何一个类中用类A 创建了一个对象后,该对象能访问自己的public变量和类中的public方法。如: class B{
2.共有变量和共有方法 用public修饰的成员变量和方法被称为共有变量和共有方法,如: class A { public float weight; //weight被修饰为public的float型变量。 public float f(float a,float b){ //方法 f是public方法。 } 当我们在任何一个类中用类A 创建了一个对象后,该对象能访问自己的public变量和类中的public方法。如: class B{ void g(){ A a=new A(); a.weight=23f; //合法。 a.f(3,4); //合法。 2017/2/24 46

47 3.友好变量和友好方法 不用private、public 、protected修饰符的成员变量和方法被称为友好变量和友好方法,如:
class A { float weight; //weight是友好的float型变量。 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); //合法。 在源文件中编写命名的类总是在同一包中的。如果源文件使用import语句引入了另外一个包中的类,并用该类创建了一个对象,那么该类的这个对象将不能访问自己的友好变量和友好方法。 2017/2/24 47

48 4.受保护的成员变量和方法 用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法,如:
class A{ protected float weight; //weight被修饰为protected的float型变量。 protected float f(float a,float b) { //方法 f是protected方法。 } 当在另外一个类中用类A创建了一个对象后,如果这个类与类A在同一个包中,那么该对象能访问自己的protected变量和protected方法。在任何一个与A同一包中的类中,也可以通过类A的类名访问类A的protected类变量和protected类方法。 假如B与A是同一个包中的类,那么类B中的a.weight和a.f(3,4)都是合法的。 class B{ void g(){ Tom a=new Tom(); a.weight=23f; //合法 a.f(3,4); //合法 在后面讲述类继承时,我们会阐述友好成员和受保护成员的区别。 2017/2/24 48

49 可以在任何另外一个类中,使用public类创建对象。如果一个类不加public修饰,如: class A {
类声明时,如果关键字class前面加上public关键字,就称这样的类是一个public类,不能用protected和private修饰类。如: public class A{ … … } 可以在任何另外一个类中,使用public类创建对象。如果一个类不加public修饰,如: class A { 这样的类被称为友好类,那么另外一个类中使用友好类创建对象时,要保证它们是在同一包中。 2017/2/24 49

50 6.关于构造方法 private、public 、protected修饰符的意义也同样适合于构造方法。
如果一个类没有明确地声明构造方法,那么public类的默认构造方法是public的,友好类的默认构造方法是友好的。 需要注意的是,如果一个public类定义声明的构造方法中没有public的,那么在另外一个类中使用该类创建对象时,使用的构造方法就不是 public的,创建对象就受到一定的限制。 假设对象a是A类创建的,我们把对象对成员的访问权限总结在下表4.1中 2017/2/24 50

51 对象的组合 一个类可以把对象作为自己的成员变量,如果用这样的类创建对象,那么该对象中就会有其它对象,也就是说该对象将其他对象作为自己的组成部分(这就是人们常说的Has-A),或者说该对象是由几个对象组合而成 .例子17 2017/2/24 51

52 Java的基本数据类型包括byte、int、short、long、float、double、char。
4.14 基本类型数据的类包装 Java的基本数据类型包括byte、int、short、long、float、double、char。 Java同时也提供了基本数据类型相关的类,实现了对基本数据类型的封装。这些类在java.lang包中,分别是Byte、Integer、Short、Long、Float、Double和Character类。 2017/2/24 52

53 1.Double和Float类 Double类和Float类实现了对double和float基本型数据的类包装。
Double (double num) 创建一个Double类型的对象; 使用Float类的构造方法 Float (float num) 创建一个Float类型的对象。 Double对象调用doubleValue()方法可以返回该对象含有的double型数据;Float对象调用floatValue()方法可以返回该对象含有的float型数据。 Byte、Integer、Short和Long对象分别调用byteValue ()、intValue()、shortValue ()和longValue ()方法可以返回该对象含有的基本型数据。 2017/2/24 53

54 2. Byte、Integer、Short和Long 类
Byte(byte num) Integer(int num) Short(short num) Long(long num) Byte、Integer、Short和Long对象分别调用byteValue()、intValue()、shortValue()和longValue()方法可以返回该对象含有的基本类型数据。 2017/2/24 54

55 3.Character类 Character (char c)
创建一个Character类型的对象。Character对象调charValue()方法可以返回该对象含有的char型数据。 Character类还包括一些类方法,这些方法可以直接通过类名调用,用来进行字符分类,比如判断一个字符是否是数字字符或改变一个字符的大小写等。 Character类中的一些常用类方法: public static boolean isDigit(char ch) 如果ch是数字字符方法返回true,否则返回false。 public static boolean isLetter(char ch) 如果ch是字母字符返回true,否则返回false。 public static boolean isLetterOrDigit(char ch) 如果ch是数字字符或字母字符返回true,否则返回false。 public static boolean isLowerCase(char ch) 如果ch是小写字母字符返回true,否则返回false。 public static boolean isUpperCase(char ch) 如果ch是大写字母字符返回true,否则返回false。 public static char toLowerCase(char ch) 返回ch的小写形式。 public static char toUpperCase(char ch) 返回ch的大写形式。 public static boolean isSpaceChar(char ch) 如果ch是空格返回true 2017/2/24 55

56 例子4-18 及 效果图 在下面的例子18中,将一个字符数组中的小写字母变 成大写字母,并将大写字母变成小写字母。 2017/2/24 56

57 4.15 对象数组 数组是相同类型变量按顺序组成的集合。
4.15 对象数组 数组是相同类型变量按顺序组成的集合。 如果程序需要某个类的若干个对象,正确的做法是使用对象数组,即数组的元素是对象,例如: Integer [] m; m = new Integer [10]; 需要注意的是,上述代码仅仅定义了数组m有10个元素,并且每个元素都是一个Integer类型的对象,但这些对象目前都是空对象,因此在使用数组m中的对象之前,应当创建数组所包含的对象,例如: m[0] = new Integer (120); 在下面的例4-19使用了对象数组。 2017/2/24 57

58 4.16 反编译和文档生成器 ◆使用SDK提供的反编译器javap.exe可以将字节码反编 译为源码,查看源码类中的public方法名字和public成员变量的名字,例如: javap java.awt.Button 将列出Button中的public方法和public成员变量。下列命令 javap –privae 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 2017/2/24 58

59 4.17 jar文件 Java应用程序在运行时,需要将使用到的类的字节加载到内存,因此,对字节码文件所在的位置就有着特殊的要求。
1.使用当前应用程序所在目录中没有包名的类 对于当前应用程序所在目录中没有包名的类,可直接加载使用。 2.使用Java运行环境中类库中的类 Java运行环境所提供的类库中的类都是有包名的,应用程序必须使用import语句引入相应包中的类。 3.使用应用程序当前目录的子孙目录中的类 应用程序当前目录下的子孙目录可以作为用户自定义包的包名,具有该包名的类必须存放在这些子孙目录中,应用程序就可以使用import语句引入用户自定义包中的类了。 4.使用Java运行环境扩展中的类 可以使用jar.exe命令把一些类的字节码文件压缩成一个jar文件,然后将这个jar文件存放到Java运行环境的扩展中,即将该jar文件存放在JDK安装目录的jre\lib\ext文件夹中。这样,Java应用程序就可以使用这个jar文件中的类来创建对象了。 2017/2/24 59

60 使用Java运行环境扩展中的类——压缩一个jar文件(1)
(1)有包名的类 TestOne和TestTwo类的包名为moon.star ,将上述源保存到C:\1000\moon\star目录中,然后进入该目录分别编译这两个源文件。 将C:\1000\moon\star目录中的TestOne.class 和TestTwo.class压缩成一个jar文件(Jerry.jar)的过程: 首先编写一个清单文件hello.mf(Manifestfiles)并保存到C:\1000目录中. 。 然后使用jar命令来生成一个名字为Jerry.jar C:\1000\jar cfm Jerry.jar hello.mf moon\star\TestOne.class moon\star\TestTwo.class 或 C:\1000\jar cfm Jerry.jar hello.mf moon\star\*.class 最后将jar命令在C:\1000目录中生成的Jerry.jar文件复制到Java运行环境的扩展中(JDK安装目录的jre\lib\ext文件夹中)。 下面的Use类中使用import语句引入了Jerry.jar中的 TestOne、TestTwo类。 import moon.star.*; public class Use{ public static void main(String args[]){ TestOne a=new TestOne(); a.fTestOne(); TestTwo b=new TestTwo(); b.fTestTwo(); } 2017/2/24 60

61 使用Java运行环境扩展中的类——压缩一个jar文件(2)
(2)无包名的类 如果TestOne和TestTwo类没有包名,只需将TestOne.java和TestTwo保存到C:\1000 中、编译得到字节码文件。 首先将(1)中清单文件hello.mf中类的包名去掉后保存到c:\1000中。 然后进入到C:\1000目录,使用jar命令: C:\1000\jar cfm Jerry.jar hello.mf TestOne.class TestTwo.class 如果C:\1000只有TestOne.class 和TestTwo.class两个字节码文件,也可如下使用jar命令: C:\1000\jar cfm Jerry.jar hello.mf *.class 最后将jar命令在C:\1000目录中生成的Jerry.jar文件复制到JDK安装目录的jre\lib\ext文件夹中,应用程序就可以直接使用Jerry.jar文件中的TestOne.class 和TestTwo.class。 2017/2/24 61

62 2017/2/24 62


Download ppt "本章导读 类声明和类体及其构成 第4章 类与对象 本章导读 import语句 构造方法与对象的创建 访问权限 对象的引用与实体"

Similar presentations


Ads by Google