1、第第3 3章类和对象章类和对象类和对象2主要内容主要内容n3.1 概述概述n3.2 类类n3.3 对象的定义和使用对象的定义和使用n3.4 实例变量、实例方法和类变量、类方法实例变量、实例方法和类变量、类方法n3.5 this 关键字关键字n3.6 包包n3.7 内部类和匿名类内部类和匿名类n3.8 访问控制和类的封装性访问控制和类的封装性类和对象33.1 概述概述n3.1.1 对象(object)n3.1.2 类(class)n3.1.3 消息(message)n3.1.4 面向对象系统的特性n1.抽象性(abstract)n2封装性(encapsulation)n3继承性(inherita
2、nce)n4多态性(polymorphism)类和对象43.1.1 对象对象n在面向对象系统中,对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务构成。属性和服务是构成对象的两个主要因素,属性是一组数据结构的集合,表示对象的一种状态,对象的状态只供对象自身使用,用来描述静态特性,而服务是用来描述对象动态特征(行为)的一个操作序列,是对象一组功能的体现。类和对象53.1.1 对象对象n对象的主要特性:1对象标识对象标识2属性属性3方法方法4模块独立性模块独立性5动态连接性动态连接性6易维护性易维护性类和对象63.1.2 类类n在面
3、向对象的编程语言中,类(class)是一个独立的程序单位,是对具有相同属性和方法的一组对象的抽象。通过类可以对属于该类的全部对象进行统一的描述。因此,在定义对象之前应先定义类。描述一个类需要指明下述三个方面:n(1)类标识(即类名)n(2)属性说明n(3)类的方法类和对象73.1.3 消息消息n消息(message)是面向对象系统中实现对象间的通信和请求任务的操作,是要求某个对象执行其中某个功能操作的规格说明。发送消息的对象称为发送者,接受消息的对象称为接收者。对象间的联系,只能通过消息来进行。对象在接收到消息时才被激活。类和对象83.1.3 消息消息n消息具有三个性质:(1)同一对象可接收不
4、同形式的多个消息,产生不同的响应。(2)相同形式的消息可以送给不同对象,所做出的响应可以是截然不同的。(3)消息的发送可以不考虑具体的接收者,对象可以响应消息,也可以对消息不予理会,对消息的响应并不是必需的。类和对象93.1.4 面向对象系统的特性面向对象系统的特性n1抽象性(抽象性(abstract)n2封装性(封装性(encapsulation)n3继承性(继承性(inheritance)n4多态性(多态性(polymorphism)类和对象103.2 类类n进行Java程序设计,实际上就是定义类的过程。一个Java源程序文件往往是由许多个类组成的。从用户的角度看,Java源程序中的类分为
5、两种:n 1.系统定义的类,即Java类库。n基类:所有JAVA的类都派生自ObjectnJava的类可组织在包(package)中nJava提供的标准类库分布在一系列的包中,如java.lang,java.awt,等,jdk1.1后加入javax.swing等n2.用户自己定义的类。n编程的过程就是继承基类或标准类而创建、定义特殊子类的过程类和对象113.2.1 类的定义类的定义nJava中类包括成员变量成员变量和成员方法成员方法两部分。类的成员变量可以是基本数据类型的数据或数组,也可以是一个类的实例;类的方法用于处理该类的数据。n 1.类的定义格式:类的修饰字类的修饰字 class 类名称
6、类名称 extends 父类名称父类名称implements 接口名称列表接口名称列表 变量定义及初始化;变量定义及初始化;方法定义及方法体;方法定义及方法体;类体类体类和对象12n类的修饰字:类的修饰字:public|default(public|default(可缺省,非公开类可缺省,非公开类)abstract|final abstract|final npublic:允许其他类(没有限制)访问本类,一个源文件仅可以有一个public类,且与文件同名。ndefault(缺省):可被当前包中的其他类访问;如果定义时没有public,则所有的类都是friendly;nabstract:没有实例
7、的抽象概念类,将一个类声明为抽象类,没有实现方法,需要子类提供方法的实现,所以不不能创建该类的实例能创建该类的实例。nfinal:不能再被扩展,不包含子类的类;易于安全性的实现,或用于创建固定功能的类。将一个类声明为最终类即非继承类,不能再被其它类所继承不能再被其它类所继承。关于类定义的说明关于类定义的说明类和对象13n类的修饰字:类的修饰字:public|default(public|default(可缺省,非公开类可缺省,非公开类)abstract|final abstract|final n每个类都拥有自己的名字空间,即指类及其方法和变量可每个类都拥有自己的名字空间,即指类及其方法和变量
8、可以在一定的范围内知道彼此的存在,可以使用。以在一定的范围内知道彼此的存在,可以使用。n父类继承声明:extends 父类名(见继承)n实现接口(interface):implements 接口名关于类定义的说明关于类定义的说明类和对象142.类定义中成员变量的声明类定义中成员变量的声明n修饰符n访问控制符(访问权限)访问控制符(访问权限)npublic:可被所有其他类引用nprotected:该类自身、子类、同一包中的其他类nprivate:仅可被该类自身引用和修改,不能被其他任何类(包括子类)引用ndefault(缺省):本包中的类变量修饰字变量修饰字 变量数据类型变量数据类型 变量名变量
9、名1,变量名变量名2=变量初值变量初值;public|protected|private|default static final transient volatile类和对象15nstatic:类变量或类字段,对所有的实例一致,引用时前缀可使用类名或对象名,属于类。nfinal:数值不变常量,定义同时应对其进行初始化nvolatile:异步控制修饰符,表示多个并发线程共享的变量,这使得各线程对该变量的访问保持一致。ntransient:与对象序列化有关。指定该变量是一个系统保留,暂无特别作用的临时性变量。16注意:注意:n除了访问控制符有多个之外,其他的修饰符都只有一个。除了访问控制符有多个
10、之外,其他的修饰符都只有一个。n一个成员变量可以被两个以上的修饰符同时修饰,但有些一个成员变量可以被两个以上的修饰符同时修饰,但有些修饰符是不能同时定义在一起的。修饰符是不能同时定义在一起的。n在定义类的成员变量时,可以同时赋初值,但在定义类的成员变量时,可以同时赋初值,但对成员变量对成员变量的操作只能放在方法中的操作只能放在方法中。类和对象173.类定义中方法的声明类定义中方法的声明方法修饰字方法修饰字 返回类型返回类型 方法名称方法名称(参数参数1,参数参数2,)throws exceptionList (statements;)/方法体:方法的内容方法体:方法的内容public|prot
11、ected|private|default 访问控制符访问控制符(权限权限)static final|abstract native synchronized类和对象18修饰符修饰符(Modifier):):nstatic:静态方法,又称类方法n指定不需要实例化一个对象就可以激活的方法指定不需要实例化一个对象就可以激活的方法n使用类名或对象名作为前缀,建议使用类名使用类名或对象名作为前缀,建议使用类名n在方法体中只能使用在方法体中只能使用static变量和变量和static方法或方法或访访问自己的局部变量问自己的局部变量nabstract:只有接口没有语句,只有接口没有语句,要在子类中通过重要
12、在子类中通过重新定义(新定义(override)来实现)来实现nfinal:不能被重新定义(不能被重新定义(override)。指定该方法。指定该方法不能被重载。不能被重载。19修饰符修饰符(Modifier):):nsynchronized:同步修饰符。同步修饰符。在多线程中,该修饰在多线程中,该修饰符用于在运行前,对它所属的方法加锁,以防止符用于在运行前,对它所属的方法加锁,以防止其它线程访问,运行结束后解锁。其它线程访问,运行结束后解锁。nnative:本地修饰符。本地修饰符。指定此方法的方法体是用其指定此方法的方法体是用其它语言(如它语言(如C语言)在程序外部编写的。语言)在程序外部编
13、写的。20例:例:定义圆类定义圆类 Circle.javapublic class Circle final double PI=3.14;/常量常量PI private double radius=1;/私有成员变量私有成员变量radius,表示圆的半径,表示圆的半径 private double area;/私有成员变量私有成员变量area,表示圆的面积,表示圆的面积 private static int numberOfObjects=0;/类变量,创建的圆的个数类变量,创建的圆的个数 public Circle()/以半径以半径1创建一个圆,圆的个数加创建一个圆,圆的个数加1 area
14、=PI*radius*radius;/设置圆的面积设置圆的面积 numberOfObjects+;/以半径以半径radius(指形参指形参radius)创建一个圆,圆的个数加创建一个圆,圆的个数加1 public Circle(double radius)this.radius=radius;area=PI*radius*radius;/设置圆的面积设置圆的面积 numberOfObjects+;【程序解析】该类中定义了私有成员变量【程序解析】该类中定义了私有成员变量radius,而,而第二个构造第二个构造方法方法的形参的形参radius与其同名,在方法体内成员变量与其同名,在方法体内成员变量
15、radius被隐藏,所以使被隐藏,所以使用用this关键字访问成员变量。关键字访问成员变量。类和对象21/获取圆的半径获取圆的半径 public double getRadius()return radius;/设置圆的半径设置圆的半径 public void setRadius(double radius)this.radius=(radius=0)?radius:0;/获取圆的个数获取圆的个数 public static int getNumberOfObjects()return numberOfObjects;/返回圆的面积返回圆的面积 public double getArea()r
16、eturn area;【程序解析】【程序解析】该类的定义中没有使用该类的定义中没有使用setArea()方法设置圆的面积,而是在创方法设置圆的面积,而是在创建一个圆时就设置了圆的面积,符合自然规律。当使用建一个圆时就设置了圆的面积,符合自然规律。当使用setRadius方法重新方法重新设置圆的半径时,相应地修改圆的面积。设置圆的半径时,相应地修改圆的面积。c1.java类和对象22【程序解析】【程序解析】n该类中定义了私有成员变量radius,而方法setRadius中的局部变量radius与其同名,在setRadius方法体内成员变量radius被隐藏,所以使用this关键字访问成员变量。s
17、etRadius方法的功能是:若形参radius的值大于等于0,则把形参radius的值赋给成员变量radius,否则给成员变量radius赋值为0。n该类的定义中没有使用setArea()方法设置圆的面积,而是在创建一个圆时就设置了圆的面积,符合自然规律。当使用setRadius方法重新设置圆的半径时,相应地修改圆的面积。类和对象233.2.2 方法重载方法重载n如果几个方法的方法名相同,只是方法形参个数或形参类型有所不同,则称这几个方法为重载方法。n注意:如果几个方法的方法名、方法的形参个数和形参类型均相同,只是方法的返回值类型不同,则不称其为重载方法,编译时会出错。n例如有如下的两个重载
18、方法说明:int max(int num1,double num2);double max(double num1,int num2);n当使用max(1,4)方法调用时,编译器不能确定调用哪一个方法更合适,这称为方法调用的二义性,二义性的方法调用会引起编译时的错误。类和对象243.2.3 构造方法构造方法n方法名和所在类的类名完全相同的方法称为构造方法。n构造方法具有下列特性:(1)构造方法名必须和类名完全相同。(2)构造方法不具有任何返回值类型,如果写上任何一种返回值类型(包括关键字void)则该方法不再是构造方法,而成为普通的成员方法。(3)构造方法也可以重载。重载构造方法的目的是使类对
19、象具有不同的初始值,为类对象的初始化提供方便。类和对象253.2.3 构造方法构造方法(4)当使用new运算符创建对象时,系统会自动调用构造方法,构造方法起着初始化对象的作用。(5)当在一个类中没有显式定义构造方法时,系统会提供一个默认构造方法。默认构造方法没有任何形式参数,并且方法体为空。(6)不能使用static、final、abstract、native和synchronized修饰符修饰构造方法。n注意:只要用户定义了构造方法(不一定是无参构造方法),Java语言就不再提供默认的构造方法。如果为类定义了一个带参数的构造方法,还想使用无参构造方法,则用户必须自己定义。建议用户自定义类的无
20、参构造方法。类和对象263.3 对象的定义和使用对象的定义和使用n在程序中创建对象的目的是使用对象。创建一个对象就要为对象的各个成员变量分配存储空间。类和对象273.3.1 创建对象创建对象n创建一个类,就创建了一种新的数据类型。n创建对象也称为类的实例化。n创建对象包括两个步骤:声明对象引用变量(即对象名)和实例化对象(即为对象分配存储空间)或者将两个步骤合二为一。类和对象283.3.1 创建对象创建对象1声明对象声明对象类名类名 对象名表对象名表;n其中:类名是指对象所属类的名字,它是在声明类时定义其中:类名是指对象所属类的名字,它是在声明类时定义的;对象名表是指一个或多个对象名,若为多个
21、对象名时,的;对象名表是指一个或多个对象名,若为多个对象名时,对象名之间用半角逗号进行分隔。对象名之间用半角逗号进行分隔。如下述语句声明了如下述语句声明了circleOne和和circleTwo两个两个Circle类的对象引用类的对象引用变量变量:Circle circleOne,circleTwo;n注意:声明对象实质上是声明了对象引用变量,而并没有注意:声明对象实质上是声明了对象引用变量,而并没有为对象开辟内存空间,对象引用变量存放对象的内存单元为对象开辟内存空间,对象引用变量存放对象的内存单元起始地址。起始地址。类和对象293.3.1 创建对象创建对象2为对象分配内存空间为对象分配内存空
22、间n使用使用new运算符和类的构造方法为声明的对象分运算符和类的构造方法为声明的对象分配内存空间,如果类中没有显式定义构造方法,配内存空间,如果类中没有显式定义构造方法,系统会调用默认的无参构造方法。系统会调用默认的无参构造方法。n为对象分配内存空间的格式如下为对象分配内存空间的格式如下:n对象名对象名=new 构造方法构造方法(实参列表实参列表);n例如例如:ncircleOne=new Circle();/此时此时circleOne引用被分配内存空间的真实地址引用被分配内存空间的真实地址ncircleTwo=new Circle(2.0);类和对象303.3.1 创建对象创建对象n为对象分
23、配内存空间的格式有如下两种方式:为对象分配内存空间的格式有如下两种方式:n(1)对象名对象名=new 构造方法构造方法(实参列表实参列表);circleOne=new Circle();/此时此时circleOne引用被分配内存空间的真实地址引用被分配内存空间的真实地址circleTwo=new Circle(2.0);n(2)类名类名 对象名对象名=new 构造方法构造方法(实参列表实参列表);Circle circleTwo=new Circle(2.0);建议建议读者在创建对象时读者在创建对象时采用方式采用方式(2)一一步完成:步完成:类和对象313.3.2 对象的使用对象的使用n创建一
24、个对象就要为对象的各个成员变量分配存储空间。可以通过引用对象的成员来使用对象,对象成员变量的引用方式如下:对象名对象名.成员变量名成员变量名n 对象成员方法的引用方式如下:对象名对象名.成员方法名成员方法名(实参列表实参列表)n 具体应用参见【例3.1】类和对象32【例例3.1】类和对象33【例例3.1】类和对象343.3.3 对象的清除对象的清除nJava运行时系统通过垃圾自动回收机制周期性地释放无用对象所使用的内存,完成垃圾的自动回收。当一个对象的引用为空时,该对象称为一个无用对象。垃圾收集器以较低优先级在系统空闲周期中执行,一次垃圾的收集速度比较慢,在某些情况下,我们也可以通过调用Sys
25、tem类的gc()方法,即调用System.gc()显示执行垃圾收集。类和对象353.3.3 对象的清除对象的清除n析构方法finalize()。n在对象被回收前,Java垃圾收集器通常会调用对象的finalize()方法,释放当前对象所使用的资源。但是Java系统不保证在回收实例对象所占据的存储单元之前一定会调用finalize()方法。n虽然Java使用垃圾自动回收机制,可以自动完成对内存资源的回收。但在有些情况下当一个对象被破坏后,需要执行一些垃圾收集器不能处理的特殊清理工作,要用到finalize()方法。n垃圾收集器自动调用对象的finalize(),释放当前对象所使用的资源。gc(
26、)方法调用finalize()。类和对象363.3.4 方法的参数传递方法的参数传递n进行方法调用时,需要提供实参,他们必须与方法定义中所对应的形参次序相同,这叫做参数顺序匹配。n实参必须与方法头中的形参在次序上和数量上匹配,在类型上兼容。类型兼容是指不需要经过显式的类型转换,实参的值就可以传递给形参,例如将int型的实参值传递给double型形参。n方法调用的格式有以下3种形式:n形式一:成员方法名(实参列表)n形式二:表达式.成员方法名(实参列表)n形式三:类名.静态成员方法名(实参列表)类和对象373.3.4 方法的参数传递方法的参数传递n在Java的方法调用中,方法中的参数是以传值传值
27、的形式进行的,不管它是什么数据类型。如果是基本数据类型,则将实参的值传递给形参,改变方法内部的形参的值不会影响方法外部的实参值。n无论形参在方法中如何改变,实参均不受影响。如果是类类型,则传入的是引用的一个拷贝。n如同可以给方法传递基本数据类型一样,也可以向方法传递类类型的对象,称其为引用传递。引用传递传入的是引用的一个拷贝,归根结底还是传的值。n例3.2 TestPassParameter.Java类和对象383.4 实例变量、实例方法和类变量、类方法实例变量、实例方法和类变量、类方法n3.4.1 变量与方法变量与方法n3.4.2 变量的作用域变量的作用域n3.4.3 变量的初始值变量的初始
28、值类和对象393.4.1 变量与方法变量与方法n在类的数据成员和方法成员前用static关键字修饰的分别称为类变量类变量和类方法类方法,也称为静态变量和静态方法,非静态的又分别称为实例变实例变量和实例方法量和实例方法。n在生成每个类的实例对象时,Java运行时系统为每个对象分配一块内存,然后可以通过对象引用变量来访问这些对象的实例变量。不同对象的实例变量是不同的。类和对象403.4.1 变量与方法变量与方法n类变量只在系统加载其所在类时分配空间并初始化,并且在创建该类的对象时将不再分配空间,所有的对象将共享共享类变量。每个对象对类变量的改变都会直接影响到其他对象。n类变量类变量可用来在实例对象
29、之间进行通信或跟踪该类实例的数目。n对于不是private类型的类变量,建议通过类名直接访问类通过类名直接访问类变量变量,而不像实例变量那样需要通过实例对象才能访问。类和对象413.4.1 变量与方法变量与方法注意:(1)Java中没有全局变量,但类变量是在一个类的所有实例对象中都可以访问的变量,在一定程度上类似于其他语言中的全局变量。(2)实例方法可以对当前对象的实例变量进行操作,也可以对类变量进行操作,但类方法不能访问实例变量。类和对象423.4.1 变量与方法变量与方法n实例方法的调用形式如下:对象名对象名.实例方法名实例方法名(实参列表实参列表);n类方法由类名直接调用,其调用形式如下
30、:类名类名.类方法名类方法名(实参列表实参列表);类和对象433.4.1 变量与方法变量与方法关于类方法的使用,有如下一些限制:n在类方法中没有this关键字,不能访问所属类的实例变量和实例方法,只能访问方法体内定义的局部变量、该方法的形式参数和类变量;n在类方法中不能使用super和this关键字;nmain()方法是一个静态方法。因为它是程序的入口点,这可以使JVM不创建实例对象就可以运行该方法。n【例3.3】TestClassAndInstance.Java类和对象443.4.2 变量的作用域变量的作用域n实例变量和类变量的作用域是整个类,它们可以在类中任何位置说明。n在方法中说明的变量
31、称为局部变量,局部变量的作用域从声明它的位置开始到包含它的块尾。n类的实例变量和类变量只能声明一次,但是局部变量可以在互不嵌套的块内多次声明,在同一嵌套块中只能声明一次。n【例3.4】CircleNew.java类和对象453.4.3 变量的初始值变量的初始值n如果没有对类的成员变量赋初值,则Java会对其赋默认值,对不同类型的成员变量赋以不同的默认值,如下所示:n注意:对于方法体内的局部变量,Java不提供初始值。程序员必须对其赋初值,否则会出现编译错误。类和对象463.5 this关键字关键字n关键字this用来指向当前对象或类的实例变量用来指向当前对象或类的实例变量。如果局部变量与实例变
32、量重名,则局部变量优先,同名的实例变量或类变量被隐藏。n用“类名.类变量名”可以访问隐藏的类变量,用this关键字可以访问隐藏的实例变量。n例1:class TestThisint day=1;/实例变量dayvoid setDay(int day)/局部变量day this.day=day;类和对象473.5 this关键字关键字n当一个构造方法需要调用本类的另一个构造方法时,可以使用this关键字,同时这个调用语句应该是整个构造方法的第一个可执行语句。例2:public class Circle private double radius;public Circle(double radi
33、us)this.radius=radius;public Circle()this(1.0);public double findArea()return Math.PI*radius*radius;类和对象483.6 包包n包包(package)是Java提供的文件(即公共类)的组织方式。一个包对应一个文件夹,一个包中可以包括许多类文件。包中还可以再有子包,称为包等级。n包的作用有四个:n(1)定位类:具有相似功能的类可以放置在同一个包中,这样可以很容易地查找定位类。n(2)避免命名冲突:在开发由其他程序员共享的可复用类时,会发生命名冲突,可以把类放在不同包中,通过包名引用类可以避免命名冲突
34、。n(3)可以方便地分发软件。n(4)控制类之间的访问(参见第4章访问控制)。类和对象493.6 包包注意注意:n包是一个类名空间,同一个包中的类和接口(参见第5章)不能重名,不同包中的类可以重名。n根据Java的命名规则,包名均为小写字母。n类之间的访问控制是通过类修饰符来实现的,若类修饰符为public,则表明该类不仅可供同一包中的类访问,也可以被其他包中的类访问。n若类无修饰符,则表明该类仅供同一包中的类访问。nJava的包等级和Windows的文件组织方式完全相同,只是表示方法不同。类和对象503.6.1 包的定义包的定义n包的定义就是将源程序文件中的接口和类纳入指定的包。一般情况下,
35、Java源程序由四部分组成:n(1)一个包(package)定义语句(可选项)。其作用是将本源文件中的接口和类纳入指定包。源文件中若有包说明语句,必须是第一个语句;n(2)若干个(import)语句(可选项)。其作用是引入本源文件中所需要使用的包;n(3)一个public的类声明。在一个源文件中只能有一个public类;n(4)若干个属于本包的类声明(可选)。类和对象513.6.1 包的定义包的定义n包的定义语句格式:npackage 包名包名1.包名包名2.包名包名3;n创建包就是在当前文件夹下创建一个子文件夹,存放这个包中包含的所有类和接口的.class文件。n语句中的符号“”代表了目录分
36、隔符目录分隔符,说明这个语句创建了两个文件夹。类和对象523.6.1 包的定义包的定义n习惯上,包名都用小写字母。Java规定,如果一个Java文件中有package语句,那么package语句必须写在Java源程序的第一行,该行前只能有空格和注释行。Package语句在每个Java源程序中只能有一条,一个类只能属于一个包。例如下述语句:n package cn.edu.hebiace;类和对象533.6.1 包的定义包的定义n 定义了包,语句中的包名分隔符“.”相当于目录分隔符。使用package语句指定一个源文件中的类属于一个特定的包。Java要求包名与文件系统的目录结构一一对应。n对于名
37、为cn.edu.hebiace的包,必须创建一个如图所示的目录结构。类和对象543.6.1 包的定义包的定义n 若源文件中未使用package语句创建包,则该源文件中的接口和类位于Java的无名包中(无名包又称默认包,指当前目录),会把源文件中的类存储在当前目录(即存放Java源文件的目录)下。n无名包中的类不能被其他包中的类引用和复用类和对象553.6.2 设置类路径设置类路径n包是一种组织代码的有效手段,包名指出了程序中需要使用的.class文件的所在之处。另一个能指明.class文件所在的位置是环境变量CLASSPATH。n在WindowsXP或Windows2000中可以通过设置“我的
38、电脑”属性来设置系统的环境变量。n对于Java Application程序,还可以通过为Java解释器设置参数来指定类文件路径。例如,对于JDK中的Java解释器java.exe,有开关参数-classpath;假设当需要解释执行的test.class文件不在当前目录而在e盘的TEMP目录下时,可以使用如下的命令行语句:njava-classpath e:temp Testn来运行这个程序。类和对象563.6.3 包的使用包的使用nJava提供了丰富的标准类来帮助程序设计者更方便快捷地编写程序,这些标准类组成了类包,主要有:java.lang java.awtjava.applet java.
39、awt.imagejava.awt.peer java.utiln使用Swing组件进行GUI设计,使用javax.swing包中的类n除了java.lang之外,其余类包都不是java语言所必须的。若要使用,必须进行包的导入。类和对象57n将类组织成包的目的是为了更好地利用包中的类。通常一个类只能引用与它在同一个包中的类。如果需要使用其它包中的public类,则可以使用如下的几种方法。n(1)在引入的类前加包名n例如:pack1.pack2.Format.format(23.4533,2);n(2)单类型导入(single-type-import)n例如上面的语句在程序开始处增加了:n im
40、port pack1.pack2.Format;语句之后,就可以直接写成:nFormat.format(23.4533,2);n(3)按需类型导入(type-import-on-demand)nimport pack1.pack2.*;n【例3.5】按需类型导入的使用举例。类和对象583.7 内部类和匿名类内部类和匿名类n3.7.1 内部类n一个类被嵌套定义于另一个类中,称为内部类(Inner Classes)或内隐类,包含内部类的类称为外部类。n示例:参看例3.6n外部类与内部类的访问原则是:在外部类中,一般通过一个内部类的对象来访问内部类的成员变量或方法;在内部类中,可以直接访问外部类的所
41、有成员变量和方法(包括静态成员变量和方法、实例成员变量和方法及私有成员变量和方法)。类和对象593.7 内部类和匿名类内部类和匿名类内部类和其他常规类类似,有下列特征:n(1)Java将内部类作为外部类的一个成员,内部类可以调用包含它的外部类的成员变量和成员方法,所以不必把外部类的引用传递给内部类的构造方法。n(2)内部类的类名只能用在外部类和内部类自身中,内部类的类名不能与外部类的类名相同。当外部类引用内部类时,须给出完整的名称(外部类名外部类名.内部类名内部类名)。n(3)内部类只是用来支持其外部类的工作,编译后,它的名称形如“外部类名称$内部类名称.class”。n(4)内部类可以声明为
42、public、protected或private,其意义与用在类的其他成员上相同。类和对象603.7 内部类和匿名类内部类和匿名类n和普通的类一样,内部类也可以有静态的。static型内部类只能访问外部类中的static成员。若要访问非static成员,须先创建一个外部类对象,然后通过该对象进行访问。n【例3.7】静态内部类和非静态内部类举例。类和对象613.7.2 匿名类匿名类n有时在定义事件处理代码时,由于代码短小,不必再明确定义一个类,可使用匿名内部类。匿名内部类是final(最终)类,非static类,n匿名内部类将类的声明和创建类的实例一步完成。n主要应用在事件处理的代码编写中。JB
43、utton jb=new JButton(Exit);jb.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)System.exit(-1););类和对象623.7.2 匿名类匿名类n注意:在使用匿名内部类时,要记住以下几个原则:(1)匿名内部类不能有构造方法;(2)匿名内部类不能定义任何静态成员、方法和类。(3)匿名内部类不能是public,protected,private,static。(4)只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或
44、实现一个类。因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。内部类只能访问外部类的静态变量或静态方法。(5)当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果要使用外部类的方法和变量,则应该加上外部类的类名类和对象633.8 访问控制和类的封装性访问控制和类的封装性3.8.1 3.8.1 访问控制访问控制n对类的成员变量和成员方法而言,其应用范围可以对类的成员变量和成员方法而言,其应用范围可以通过施以一定的访问权限来限定。通过施以一定的访问权限来限定。修饰符修饰符同一个类同一个类同一个包同一个包子类子类全部全部publicprotected default
45、 private 类和对象643.8.1 3.8.1 访问控制访问控制注意:注意:nprivate修饰符只能用来修饰类的数据成员和成员方法,而不能用来修饰类。n修饰符private、public、protected都不能用来修饰方法中的局部变量。在大部分情况下,一个类的构造方法都是public的。但是,如果不想创建类的实例,可以定义private构造方法。类和对象653.8.2 类的封装性类的封装性n保证模块正确性的措施是由信息的隐藏性来实现的。类包括成员变量和方法两部分。那些允许其他包程序访问和修改的成员变量和方法可以定义为public类型;只允许同一个包中的其他类,以及该类的子类访问和修改
46、的成员变量可以定义为protected类型;不允许其他类(内部类除外)访问和修改的成员变量可以定义为private类型。类和对象66习题习题1设计一个复数类。要求复数类包括实部和虚部两个成员变量,同时类设计一个复数类。要求复数类包括实部和虚部两个成员变量,同时类中应包含复数运算的各种方法。最后编写程序进行测试。中应包含复数运算的各种方法。最后编写程序进行测试。2设计一个长方形类。成员变量包括长度和宽度。类中除了包含计算周设计一个长方形类。成员变量包括长度和宽度。类中除了包含计算周长和面积的方法外,还应该能够用长和面积的方法外,还应该能够用set方法来设置长方形的长度和宽度,方法来设置长方形的长
47、度和宽度,以及能够用以及能够用get方法来获得长方形的长度和宽度。最后,编写一个测试程方法来获得长方形的长度和宽度。最后,编写一个测试程序来测试所定义的长方形类能否实现预定的功能。序来测试所定义的长方形类能否实现预定的功能。要求:使用自定义包。要求:使用自定义包。3设计一个分数类。要求分数类包括分子和分母两个成员变量,同时类设计一个分数类。要求分数类包括分子和分母两个成员变量,同时类中应包含分数运算的各种方法。编写一个测试程序进行测试。中应包含分数运算的各种方法。编写一个测试程序进行测试。4设计一个日期类,其输出格式是设计一个日期类,其输出格式是“月月/日日/年年”或或“月月 日,年日,年”,并,并编写一个测试程序来测试所定义的日期类能否实现预定的功能。编写一个测试程序来测试所定义的日期类能否实现预定的功能。要求:把所设计的日期类作为测试类的内部类。要求:把所设计的日期类作为测试类的内部类。