
类与对象精选课件.ppt
86页第第3章章 类与对象类与对象13.1 面向对象思想概述面向对象思想概述l程序面对的问题域程序面对的问题域—客观世界客观世界l客观世界有很多事物客观世界有很多事物l事物有自己的状态和行为事物有自己的状态和行为l事物间有各种联系事物间有各种联系l通过事物间的联系,事物产生相互作用通过事物间的联系,事物产生相互作用l在一个面向对象系统在一个面向对象系统l对象是现实世界的事物的抽象对象是现实世界的事物的抽象l事物的状态抽象为对象的属性和方法事物的状态抽象为对象的属性和方法l事物间的关系通过对象间的关系表示事物间的关系通过对象间的关系表示l事物间的相互作用通过对象间的消息通信支持事物间的相互作用通过对象间的消息通信支持23.1.1 对象对象l客观世界由具体事物构成,客观世界由具体事物构成,每个事物由自己的一组状态每个事物由自己的一组状态和行为l把问题域中的事物抽象为对把问题域中的事物抽象为对象,状态抽象为一组数据象,状态抽象为一组数据(属性),行为抽象为一组(属性),行为抽象为一组操作服务(方法)操作服务(方法)l对象:对象:l对象标识:对象名对象标识:对象名l属性:一组数据(数据成员)属性:一组数据(数据成员)l方法:操作,服务(成员方方法:操作,服务(成员方法)法)一辆汽车一辆汽车静态特征:静态特征:颜色:蓝色颜色:蓝色型号:型号:XXXX马力:马力:100动态特征:动态特征:行驶行驶转弯转弯停车停车car1属性:属性:“blue”,,”XXXX“,,100方法:方法:move,,turn,,stop33.1.2 类类l把具有共同性质的事物归为一类,把具有共同性质的事物归为一类,得出一个抽象的概念(抽象与分得出一个抽象的概念(抽象与分类原则)类原则)l对象是对事物的抽象对象是对事物的抽象l类是对对象的抽象类是对对象的抽象l面向对象语言中面向对象语言中l类是对同类的所有对象的抽象类是对同类的所有对象的抽象描述描述l属性描述属性描述l方法描述方法描述l类类l类标识:类名类标识:类名l属性说明(属性名,属性类型)属性说明(属性名,属性类型)l方法说明与实现方法说明与实现对象:对象:car1属性:属性:“blue”,,”XXXX“,,3方法:方法:move,,turn,,stop对象:对象:car2属性:属性:“red”,,”YYYY“,,2.5方法:方法:move,,turn,,stop类:类:Car属性说明:属性说明:color 字符串,字符串,type 字符串,字符串,horsePower 整数整数方法说明与实现:方法说明与实现:move,,turn,,stop4类与对象的关系类与对象的关系l抽象与具体的关系抽象与具体的关系l类是同类对象的抽象描述类是同类对象的抽象描述l对象是符合类描述的具体事物对象是符合类描述的具体事物l我们称:对象是类的实例我们称:对象是类的实例l程序程序l先定义类先定义类l创建类的对象,完成系统功能创建类的对象,完成系统功能模具模具----零件零件类型类型-----变量变量53.1.3 消息通信消息通信l把对象之间产生相互作用所传递的信息称做消息。
把对象之间产生相互作用所传递的信息称做消息l通过给对象发送消息请求对象提供服务,实现对象间的协通过给对象发送消息请求对象提供服务,实现对象间的协作,完成相应的功能作,完成相应的功能l消息格式:消息格式:l接收消息的对象,请求的功能,传递的数据接收消息的对象,请求的功能,传递的数据l返回的结果返回的结果car2.move其他对象或全局函数对象:对象:car2属性:属性:“red”,,”YYYY“,,2.5方法:方法:move,,turn,,stop消息消息对象的方法就是对象能提供的功能(服务),给对象发消息就是调用对象对象的方法就是对象能提供的功能(服务),给对象发消息就是调用对象的方法63.1.4 对象之间的关系对象之间的关系l事物之间的关系体现为对象之间的关系事物之间的关系体现为对象之间的关系l对象之间有关系,才能进行消息通信对象之间有关系,才能进行消息通信l对象间关系的表示对象间关系的表示73.2 类类lJava程序设计过程就是定义类的过程程序设计过程就是定义类的过程l定义类定义类l定义类的对象及之间交互定义类的对象及之间交互lJava的类的类l系统定义的类(通用的类:输入输出,界面等)系统定义的类(通用的类:输入输出,界面等)l自定义的类(特定应用相关的类)自定义的类(特定应用相关的类)8【【例例3-1】】矩形形状类矩形形状类class Rectangle{int width;int height;void area(){int a=width*height;System.out.println("面积为面积为"+a);}void perimeter(){int a=2*(width+height);System.out.println("周长为周长为"+a);}}93.2.1 类定义类定义[修饰符修饰符] class 类名类名 [extends 父类名父类名] [implements 接口名列表接口名列表] {数据成员声明数据成员声明成员方法声明与实现成员方法声明与实现}l类头类头l必须项:必须项:class 类名类名l可选项可选项l[extends 父类名父类名] [implements 接口名列表接口名列表]l类的修饰符类的修饰符:[public] [abstract | final] l类体类体103.2.2 数据成员定义数据成员定义l数据成员要在类体中声明数据成员要在类体中声明[修饰符修饰符] 数据类型数据类型 变量名;变量名;l 必须项:数据类型必须项:数据类型 变量名;变量名;l可选项:可选项:l数据成员修饰符:数据成员修饰符:[public | protected | private] [static] [final] [transient] [volatile] 113.2.3 成员方法的定义成员方法的定义[修饰符修饰符] 返回类型返回类型 方法名(方法名([形参列表形参列表]))[ 抛出异常列表抛出异常列表]{语句序列语句序列}121、方法头、方法头l必须项:返回类型必须项:返回类型 方法名()方法名()l方法名方法名()l返回类型:方法返回结果的类型。
若不需要返回值,则为返回类型:方法返回结果的类型若不需要返回值,则为voidl可选项:可选项:l形参列表:形参列表:类型名类型名 形参名形参名1,类型名,类型名2 形成名形成名2 ...l[ 抛出异常列表抛出异常列表]l方法的修饰符:方法的修饰符:[public | protected | private] [static] [final|abstract] [native][synchronized] 132、方法体、方法体l语句语句l使用参数使用参数l返回值与返回值与return语句语句return 表达式;表达式;结束方法执行,将表达式的值作为方法的返回结果适于返回结束方法执行,将表达式的值作为方法的返回结果适于返回类型为非类型为非void))return;;结束方法执行适于返回类型为结束方法执行适于返回类型为void))void drawRect(char c) {int side=5;for(int i=0;i 类的成员方法可以自由调用自己类的方法方法名方法名([实参列表实参列表])方法调用可以作为独立语句若有返回值,可用返回值继续参与其他运算方法调用可以作为独立语句若有返回值,可用返回值继续参与其他运算class Rectangle{int width;int height;void area(){int a=width*height;System.out.println("面积为面积为"+a);}void perimeter(){int a=2*(width+height);System.out.println("周长为周长为"+a);}void computeAndDisplay(){area();perimeter();}}175、改善、改善【【例例3-1】】class Rectangle{int width;int height;int area(){int a=width*height;return a;}int perimeter(){int a=2*(width+height);return a;}void display(){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}void computeAndDisplay (){int a = area();int p = perimeter();System.out.println("面积为面积为"+a+",周长为,周长为"+p);}18void set( int w, int h) {width=w; //用形参用形参w的值设置数据成员的值设置数据成员width的值的值height=h; //用形成用形成h的值设置数据成员的值设置数据成员height的值的值}void scale( int s ) {width=width*s;height=height*s;}}193.3 对象对象l类不是运行时存在的事物。 类不是运行时存在的事物l通过类创建其对象对象是运行时存在的具体事通过类创建其对象对象是运行时存在的具体事物类:数据类型类:数据类型对象:变量对象:变量203.3.1 创建对象创建对象l对象的创建分两步对象的创建分两步l对象声明对象声明类名类名 对象名对象名;l对象创建对象创建对象名对象名= new 类名类名( [实参列表实参列表] ) ;注:也可以合成一步 注:也可以合成一步 类名类名 对象名对象名= new 类名类名([实参列表实参列表] );Rectangle r;;r = new Rectangle(); Rectangle r1 = new Rectangle(); Rectangle r1,r2; Rectangle r1=new Rectangle(), r2=new Rectangle();21对象创建的分析对象创建的分析—引用类型引用类型对象的创建分两步:对象的创建分两步:1、对象的声明:、对象的声明:类型类型 变量名;变量名;但对象声明并不会真正创建对象,但对象声明并不会真正创建对象, (不会给对象分配内存)(不会给对象分配内存)只是创建一个引用(它的值用来指向对象)只是创建一个引用(它的值用来指向对象)2、对象创建:、对象创建:运算符运算符new创建对象(为对象分配内存空间)创建对象(为对象分配内存空间)new运算符创建对象,并返回对象的引用,将这个引用赋值给同类型的引运算符创建对象,并返回对象的引用,将这个引用赋值给同类型的引用变量,那么通过该引用变量可以找到创建的对象用变量,那么通过该引用变量可以找到创建的对象引用引用w值值h值值实际对象实际对象r1Rectangle r1;;r1=new Rectangle();223.3.2 使用对象使用对象l对象是拥有数据成员和成员方法的实体。 故对象的使用:对象是拥有数据成员和成员方法的实体故对象的使用:l访问对象的数据成员访问对象的数据成员l调用对象的成员方法调用对象的成员方法1、访问数据成员、访问数据成员对象名对象名.数据成员名数据成员名Rectangle r = new Rectangle(); r.width=5; r.height=10;Rectangle r1 = new Rectangle();r1.width=2;r1.height=3;510r23r1232、调用成员方法、调用成员方法对象名对象名. 成员方法名(成员方法名([实参列表实参列表])) l参数传递参数传递实参与形参一一对应,类型匹配实参与形参一一对应,类型匹配l方法的返回值方法的返回值方法调用表达式:可以独立为语句,或基于返回值继续参与表方法调用表达式:可以独立为语句,或基于返回值继续参与表达式等达式等l方法调用的执行过程方法调用的执行过程class Rectangle{......void set(int w, int h) {width=w;height=h;}int area(){return width*height;}......}Rectangle r = new Rectangle(); r.set(5, 10);int d;d= r.area();243、让程序运行起来、让程序运行起来l创建对象,执行功能创建对象,执行功能l消息通信消息通信l避免直接访问数据成员避免直接访问数据成员l定义主类定义主类l创建一个包含创建一个包含main方法的类方法的类l在在main方法中创建对象,完成功能方法中创建对象,完成功能class A{}public class Test{public static void main(String args[]){A a=new A();}}25class Rectangle{int width;int height;void set(int w, int h) {width=w;height=h;}int area(){int a=width*height;return a;}int perimeter(){int a=2*width*height;return a;}void display(){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}void computeAndDisplay (){int a = area();int p = perimeter();System.out.println("面积为面积为"+a+",周长为,周长为"+p);}}26public class Test{ //主类主类public static void main(String args[]){Rectangle r=new Rectangle();r.set(25, 36);r.display();rputeAndDisplay();System.out.println("--------------------------");Rectangle r1=new Rectangle();r1.set(18, 47);r1.display();r1puteAndDisplay();System.out.println("--------------------------");System.out.println("前面两个矩形中,面积较大的矩形为:前面两个矩形中,面积较大的矩形为:");if(r.area()>r1.area())r.display();elser1.display();}}27l编译:编译:两个类在一个文件里:两个类在一个文件里:Test.java(以以public类的类名命名类的类名命名)一个文件最多一个一个文件最多一个public类(这里把主类设为类(这里把主类设为public类)类)javac Test.java两个类各在一个文件里:两个类各在一个文件里:Test.java,Rectangle.javajavac Rectangle.javajavac Test.javal运行运行java Test;((Test 是是main函数所在类)函数所在类)编译完成后,每个编译完成后,每个类生成一个字节码类生成一个字节码文件文件Test.classRectangle.class283.4 方法重载方法重载l一个类中,多个方法使用同一个名字,称为方法的重载。 一个类中,多个方法使用同一个名字,称为方法的重载 l方法重载的区分方法重载的区分l参数个数不同,或参数类型不同,这样的重载是有效的方法参数个数不同,或参数类型不同,这样的重载是有效的方法重载l注意:方法名的不同,或返回值类型的不同是不能区分重载注意:方法名的不同,或返回值类型的不同是不能区分重载方法的class A{void f(int a, int b){……} void f(int a,,int b,,int c){……} void f(double a, double b){……} } A a=new A();a.f(1,1);a.f(1,2,3);a.f(1.234,0.67); 29class Rectangle{......void scale(int s) {width=width*s;height=height*s;}void scale ( int s, char type){if ( type = = 'w')width = width*s;else if ( type = = 'h')heigh = height*s;}}303.5 对象的初始化与清除对象的初始化与清除l初始化:变量(对象)在使用前应该具有确定的值。 初始化:变量(对象)在使用前应该具有确定的值l清除:当变量或对象用完,其内存应回收清除:当变量或对象用完,其内存应回收l局部变量局部变量l初始化:方法体内定义的局部变量在使用前必须已经赋值,初始化:方法体内定义的局部变量在使用前必须已经赋值,否则编译错误否则编译错误l清除:方法体内局部变量在方法结束时由系统清除清除:方法体内局部变量在方法结束时由系统清除l对象对象l初始化:初始化:l清除:清除:313.5.1 构造方法构造方法l构造方法与类同名,且没有返回值形如:构造方法与类同名,且没有返回值形如:类名(类名([形参列表形参列表])){……//语句语句}有关构造方法的几条规则:有关构造方法的几条规则:l对象创建时一定会调用构造方法对象创建时一定会调用构造方法构造方法也只能在创建对象时,构造方法也只能在创建对象时,由由Java系统自动调用,以后不能再主动调用系统自动调用,以后不能再主动调用l对象创建时必须与构造方法格式一致对象创建时必须与构造方法格式一致,即构造方法若有形参列表,,即构造方法若有形参列表,则创建对象时应传递匹配的实参列表则创建对象时应传递匹配的实参列表l若类没有定义构造方法也是可以的,若类没有定义构造方法也是可以的,Java系统会自动为类创建一系统会自动为类创建一个不带参数的构造方法个不带参数的构造方法,当然这个方法的方法体是空的,什么初,当然这个方法的方法体是空的,什么初始化操作也不做。 始化操作也不做32构造方法的重载构造方法的重载l一个类可以有多个构造方法,创建对象时,要与其中一种构造一个类可以有多个构造方法,创建对象时,要与其中一种构造方法匹配方法匹配l一旦已经定义了构造方法,一旦已经定义了构造方法,Java系统就不会再自动创建不带参系统就不会再自动创建不带参数的构造方法了数的构造方法了(即使类中定义的构造方法中并没有不带参数(即使类中定义的构造方法中并没有不带参数的构造方法)的构造方法)l不带参数的构造方法(简称无参构造方法,也常称为默认构造不带参数的构造方法(简称无参构造方法,也常称为默认构造方法,缺省构造方法)是很重要的构造方法方法,缺省构造方法)是很重要的构造方法,很多情况下会自,很多情况下会自动调用它动调用它33class Rectangle{int width;int height;Rectangle(){ //构造方法构造方法(1),不带参数,不带参数width=1;height=1;}Rectangle(int w,int h){ //构造方法(构造方法(2),带两个参数),带两个参数width=w;height=h;}void display(){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}}public class Test{public static void main(String args[]){Rectangle r=new Rectangle(); Rectangle r1=new Rectangle(3,5)r.display();r1.display();}}343.5.2 对象的初始化对象的初始化l所有的数据在使用前都应有值所有的数据在使用前都应有值l对象属性在使用前应有值(如:访问对象属性,调用对象成员对象属性在使用前应有值(如:访问对象属性,调用对象成员方法)方法)对象初始化的三种方法对象初始化的三种方法l数据成员默认值数据成员默认值l在说明数据成员时直接初始化在说明数据成员时直接初始化l使用构造方法使用构造方法35类型类型默认值默认值byte(byte)0short(short)0int0long0Lfloat0.0fdouble0.0char‘\u0000’booleanfalse引用引用null1、默认值初始化、默认值初始化l在对象创建时,其数据成员会自动被初始化为默认值在对象创建时,其数据成员会自动被初始化为默认值class A{int x;void display(){System.out.println(x);}}public class Test{public static void main(String args[]){A a=new A();a.display();int x;System.out.println(x);}}注:方法内创建的局部变量不会自动初始化注:方法内创建的局部变量不会自动初始化362、在说明类的数据成员时直接初始化、在说明类的数据成员时直接初始化class A {int a=10;Rectangle r = new Rectangle(3,5);void f(){……}}3、使用构造方法初始化、使用构造方法初始化4、初始化的执行、初始化的执行•先默认值初始化先默认值初始化•再根据声明时赋值情况,设置数据成员的值再根据声明时赋值情况,设置数据成员的值•最后调用构造方法最后调用构造方法class A {int x;int y=10;int z;Rectangle r;A(){ x=100; r=new Rectangle(); }}373.5.3 对象的清除对象的清除lJava中的对象必须通过中的对象必须通过new关键字创建关键字创建l而而Java运行时系统提供了垃圾收集机制,能监测运行时系统提供了垃圾收集机制,能监测所有用所有用new创建的对象的使用状态,当对象不再创建的对象的使用状态,当对象不再需要的时候会自动清除它们,收回内存。 需要的时候会自动清除它们,收回内存383.6 this引用引用l在类的方法中(不包含静态方法)都隐含了一个在类的方法中(不包含静态方法)都隐含了一个this引用,这引用,这个引用的类型为当前类,其指向的是调用方法的当前对象个引用的类型为当前类,其指向的是调用方法的当前对象lthis的使用方法与普通引用的使用是相同的在类的方法中可的使用方法与普通引用的使用是相同的在类的方法中可以自由使用这个引用来访问当前对象的数据成员,或针对当前以自由使用这个引用来访问当前对象的数据成员,或针对当前对象来调用方法对象来调用方法 ...int area(){int a=this.width* this.height;return a;}...Rectangle r=new Rectangle(2,3);int d = r.area(); //隐含效果隐含效果Rectangle.area( r );39this的使用的使用l返回当前对象自己返回当前对象自己l区分同名数据成员与形参区分同名数据成员与形参 l在构造方法中使用构造方法在构造方法中使用构造方法class A{int x;void f(int x){this.x=x;}}class Rectangle{int width;int height;Rectangle(int w,int h){ width=w;width=h;}Rectangle(){this(1,1); //调用第一个构造方法调用第一个构造方法}}403.7 引用类型理解与应用引用类型理解与应用l基本类型:变量声明的同时创建了特定类型的数据(进行了内基本类型:变量声明的同时创建了特定类型的数据(进行了内存分配)存分配)l引用类型:所有其他类型都为引用类型(类,数组,接口),引用类型:所有其他类型都为引用类型(类,数组,接口),其特点为:进行变量声明的时候只创建引用变量,而不创建具其特点为:进行变量声明的时候只创建引用变量,而不创建具体对象。 具体对象需要用体对象具体对象需要用new创建(分配内存)创建(分配内存)l引用与对象分离,其对应关系不固定,可以变化这样就有可引用与对象分离,其对应关系不固定,可以变化这样就有可能产生一些前面讲基本类型时没有遇到过的问题:能产生一些前面讲基本类型时没有遇到过的问题:((1)一个引用先后指向不同的对象的情况一个引用先后指向不同的对象的情况2)多个引用指向同一个对象的情况多个引用指向同一个对象的情况413.7.1 理解引用类型理解引用类型l引用支持的运算引用支持的运算l赋值赋值l==,!,!=1、赋值运算、赋值运算((1)被)被new创建的对象赋值表示:引用指向了一个对象)创建的对象赋值表示:引用指向了一个对象)((2)被同类型的引用变量赋值注意:这会引起两个引用)被同类型的引用变量赋值注意:这会引起两个引用指向同一个对象)指向同一个对象)((3)被赋值以)被赋值以null表示引用不再指向任何对象)表示引用不再指向任何对象)42class Rectangle{int width;int height;Rectangle(int width,int height) { this.width=width; this.height=height;}void set(int width,int height) {this.width=width; this.height=height;}void display( ){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}} public class Test{public static void main(String args[]){......}43Rectangle a=new Rectangle(1,2);Rectangle b=new Rectangle(3,4);a = b;a.display();b.display();a.set(5,6);a.display();b.display();a=null;b=null;a.display();//错误错误1234ab1234ab56ab一个对象如没有一个对象如没有任何引用指向它,任何引用指向它,对象就是无用的,对象就是无用的,无用的内存由无用的内存由Java垃圾收集机垃圾收集机制回收。 制回收当对象使用完当对象使用完毕时,可以将毕时,可以将引用变量赋值引用变量赋值为为nullnullnullab56442、比较运算中的、比较运算中的==,!=l两个引用变量可以进行两个引用变量可以进行相等与不等的比较,其相等与不等的比较,其比较的是引用的值,而比较的是引用的值,而不是引用所指向的对象不是引用所指向的对象是否相等是否相等l引用变量可以与引用变量可以与null进行进行相等与不等的比较,来相等与不等的比较,来判断引用变量是否指向判断引用变量是否指向了对象了对象Rectangle a = new Rectangle(3,4);Rectangle b = new Rectangle(3,4);if(a==b)System.out.println(“相等相等1”);a=b;if(a==b)System.out.println(“相等相等2”);a=null;a.display();//错误错误if (a!=null)a.display();453.7.2 方法参数传递方法参数传递l参数传递方式参数传递方式l按值传递:按值传递:Java的的基本类型基本类型数据采用这种传递方式。 数据采用这种传递方式其特点是,实参将其值传递给形参,形参是实参的一其特点是,实参将其值传递给形参,形参是实参的一个本地拷贝,对形参的操作对实参没有影响个本地拷贝,对形参的操作对实参没有影响 l按引用传递按引用传递::Java的的引用类型引用类型的对象都采用这种传递的对象都采用这种传递方式其特点是:参数传递时,实际传递的是对象的方式其特点是:参数传递时,实际传递的是对象的引用,而不是对象本身形参是引用,而不是对象本身形参是“实参引用实参引用”的一个的一个本地拷贝,这样形参会指向实参对象,通过形参引用本地拷贝,这样形参会指向实参对象,通过形参引用对对象的操作会作用到实际的实参对象上对对象的操作会作用到实际的实参对象上 46【【例例3-4】】按值传递对实参的影响按值传递对实参的影响class A{void parameterChangeTest ( int n) {n = 10;}}public class Test{public static void main(String args[]){A a = new A();int b=13;a. parameterChangeTest ( b);System.out.println (b);}}形参形参n与实参与实参b没没有直接联系,对有直接联系,对n的改变对的改变对b没影响没影响47【【例例3-5】】按引用传递对实参的影响按引用传递对实参的影响class A{void parameterChangeTest ( B n) {n.i = 10;}}class B{int i;}public class Test{public static void main(String args[]){A a = new A();B b = new B();b.i=100;a. parameterChangeTest ( b);System.out.println (b.i);}}形参形参n即代表实即代表实参对象参对象b,通过,通过n改变数据成员,改变数据成员,就是改变实参对就是改变实参对象象48【【例例3-6】】按引用传递对实参的影响按引用传递对实参的影响class A{void parameterChangeTest ( B n) {n = new B();n.i = 10;}}class B{int i;}public class Test{public static void main(String args[]){A a = new A();B b = new B();b.i=100;a. parameterChangeTest ( b);System.out.println (b.i);}}对形参引用的重新对形参引用的重新赋值对实参并没有赋值对实参并没有影响。 影响 49引用类型做参数应用引用类型做参数应用class Rectangle{int width;int height;Rectangle(){width=0;height=0;}Rectangle(int w,int h){width=w; height=h;}Rectangle(Rectangle r){ width=r.width; height=r.height;}void set(int width,int height) {this.width=width;this.height=height;}void set(Rectangle r) { width=r.width;height=r.height;}50boolean equals(Rectangle r) { return (width==r.width)&&(height==r.height); }void display(){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}}public class Test{public static void main(String args[]){Rectangle a=new Rectangle();Rectangle b=new Rectangle(3,5);Rectangle c=new Rectangle(b);System.out.println(b==c);System.out.println( b.equals(c) );}}513.7.3 返回值为引用类型返回值为引用类型l方法的返回值也可以为引用类型。 方法的返回值也可以为引用类型l当需要返回对象时,返回的实际是对象的引用,而不是对象本当需要返回对象时,返回的实际是对象的引用,而不是对象本身当将这个返回的引用赋值给某个声明的引用变量时,这个身当将这个返回的引用赋值给某个声明的引用变量时,这个引用变量会指向这个返回值(引用)指向的对象引用变量会指向这个返回值(引用)指向的对象 52【【例例3-8】】引用类型做返回值(返回当前对象)引用类型做返回值(返回当前对象)class Rectangle{int width;int height;Rectangle(int w,int h){width=w; height=h;}void set(int width,int height) {this.width=width;this.height=height;}void display(){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}Rectangle scale(int s) {width=width*s;height=height*s;return this;}53Rectangle scale(int s,char type) {if(type=='w')width=width*s;else if(type=='h')height=height*s;return this;}}public class Test{public static void main(String args[]){Rectangle a=new Rectangle(3,5);a.display();Rectangle b=a.scale(3);b.display();b.set(1,1); //语句(语句(a))a.display(); //语句(语句(b))b.display(); //语句(语句(c))}}54【【例例3-9】】引用类型做返回值(返回新对象)引用类型做返回值(返回新对象)class Rectangle{int width;int height;Rectangle(int w,int h){width=w; height=h;}void display(){System.out.println("矩形宽为矩形宽为"+width+",高为,高为"+height);}Rectangle scale(int s) {Rectangle r=new Rectangle(width*s,height*s);return r;}Rectangle scale(int s,char type) {Rectangle r;if(type=='w')r=new Rectangle(width*s,height);else if(type=='h')r=new Rectangle(width,height*s);else r=new Rectangle(width,height);return r;}}55public class Test{public static void main(String args[]){Rectangle a=new Rectangle(3,5);a.display();Rectangle b=a.scale(3);b.display();a.display();}}563.7.4 类的数据成员为引用类型类的数据成员为引用类型l一个类的数据成员可以为基本类型,也可以为引一个类的数据成员可以为基本类型,也可以为引用类型(如类的数据成员类型可以为已定义的其用类型(如类的数据成员类型可以为已定义的其它类)。 它类)l这使我们不必从头定义一个类,而是可以使用已这使我们不必从头定义一个类,而是可以使用已定义的其他类来描述类的数据成员,使类的定义定义的其他类来描述类的数据成员,使类的定义更加方便更加方便 57class Rectangle{……//此类与前面定义相同,这里省略此类与前面定义相同,这里省略}class WallPaint{Rectangle wall;double unitPrice;WallPaint(){wall=new Rectangle(0,0); unitPrice=0;}WallPaint(int w, int h, double p) {wall = new Rectangle(w,h); unitPrice=p;}void setUnitPrice(double p) {unitPrice=p;}void changeWall(int w, int h) {wall.set(w,h); //修改矩形对象修改矩形对象}58double computePay(){return unitPrice* wall.area(); }void display(){System.out.print("墙体彩绘业务:墙体彩绘业务:\n墙体墙体");wall.display();System.out.println("此笔业务单价此笔业务单价"+unitPrice);}}public class Test{public static void main(String args[]){WallPaint w=new WallPaint(2,3,125);w.display();System.out.println("总价格为:总价格为:"+wputePay() );}}593.8 作用域与生存期作用域与生存期l作用域:标识符的使用范围作用域:标识符的使用范围l生存期:运行时,标识符的存在区间生存期:运行时,标识符的存在区间603.8.1 作用域作用域l局部域:方法体内定义的标识符局部域:方法体内定义的标识符(补充(补充2.6))((1))方法的形参作用域为整个方法方法的形参作用域为整个方法,其在方法调用时通过参数传递初,其在方法调用时通过参数传递初始化。 始化2))异常处理参数作用域为其后跟的异常处理参数作用域为其后跟的{}表示的语句块表示的语句块,其在异常参数,其在异常参数传递时初始化传递时初始化l类域:在类体中(方法外)定义的标识符类域:在类体中(方法外)定义的标识符为类的数据成员和成员方为类的数据成员和成员方法,其作用域为类域法,其作用域为类域1)类的数据成员和成员方法标识符的作用域以类为单位,)类的数据成员和成员方法标识符的作用域以类为单位,在整个类在整个类内有效内有效(允许类的所有成员方法直接访问)允许类的所有成员方法直接访问)2))类的数据成员互相不能同名,类的成员方法也互相不能同名类的数据成员互相不能同名,类的成员方法也互相不能同名(因(因为在同一作用域)为在同一作用域)3)成员方法的)成员方法的局部变量可以与类的数据成员同名,但该类的数据成局部变量可以与类的数据成员同名,但该类的数据成员在方法体内被暂时屏蔽员在方法体内被暂时屏蔽但可以通过但可以通过this引用来访问该类的被屏引用来访问该类的被屏蔽的数据成员蔽的数据成员61【【例例3-12】】局部引用变量与对象局部引用变量与对象class A {int i;A(int i1){i=i1;}void display(){System.out.println(i);}}public class Test{public static void main(String args[]){A a;{A b=new A(10);b.display();a=b;}a.display();}}623.8.2 生命期生命期1、局部变量生命期、局部变量生命期l局部变量的生命期与其作用域有关。 局部变量的生命期与其作用域有关l其在程序执行流程中,当到达作用域时变量开始使用,生命期其在程序执行流程中,当到达作用域时变量开始使用,生命期开始,超出作用域则不再使用,生命期结束开始,超出作用域则不再使用,生命期结束 l内存栈区内存栈区2、数据成员生命期与对象生命期、数据成员生命期与对象生命期l数据成员生命期:数据成员随对象创建而分配内存,随对象销数据成员生命期:数据成员随对象创建而分配内存,随对象销毁而销毁,其生命期与对象生命期一致毁而销毁,其生命期与对象生命期一致l对象生命期:对象生命期:new创建时生命期开始,没有引用指向时生命期创建时生命期开始,没有引用指向时生命期结束l内存堆区:垃圾收集机制内存堆区:垃圾收集机制63class Rectangle{……//内容略内容略}class A{Rectangle r;void set(Rectangle re){r = re;}}public class Test{public static void main(String args[]){Rectangle r1 = new Rectangle(1,1);A b = new A();b.set(r1);A c = new A();c.set(r1);}}width:1height:1r1rbRectangle对象对象rc类类A对象对象堆区堆区栈区栈区……643.9 静态数据成员与静态方法静态数据成员与静态方法l实例数据成员,实例方法实例数据成员,实例方法l类数据成员,类方法(静态数据成员,静态方法)类数据成员,类方法(静态数据成员,静态方法)653.9.1 静态数据成员静态数据成员l类的静态数据成员概念类的静态数据成员概念l数据成员属于类,而不属于任何特定的对象,由类数据成员属于类,而不属于任何特定的对象,由类的所有对象共享。 的所有对象共享类:类:Student属性:属性:学号,姓名,成绩学号,姓名,成绩学生数学生数方法:显示学生信方法:显示学生信息息对象:对象:aaa“001”,,“aaa”,,89对象:对象:bbb“002”,,“bbb”,,78661、类的静态数据成员声明、类的静态数据成员声明l用用static修饰符修饰类的数据成员修饰符修饰类的数据成员2、类的静态数据成员访问、类的静态数据成员访问l类静态数据成员可类静态数据成员可通过类名直接访问通过类名直接访问,也可以,也可以通过对象访问,通过对象访问,在类的方法中直接访问在类的方法中直接访问l注意:类的静态数据成员值被所有对象共享,任何对象都可以注意:类的静态数据成员值被所有对象共享,任何对象都可以访问类的静态数据成员,但要注意,它们使用的是同一个数据,访问类的静态数据成员,但要注意,它们使用的是同一个数据,操作的是同一块内存无论哪个对象修改了它,对其它对象来操作的是同一块内存无论哪个对象修改了它,对其它对象来说,它也已经变了说,它也已经变了 67【【例例3-14】】类的静态数据成员访问类的静态数据成员访问class A{static int i ;void change(int i1) { i=i1;}}public class Test{public static void main(String args[]){A.i=10;A a=new A();A b=new A();System.out.println(A.i+","+a.i+","+b.i);a.change(40);System.out.println(A.i+","+a.i+","+b.i);b.i+=10;System.out.println(A.i+","+a.i+","+b.i);}}683、静态数据成员的初始化、静态数据成员的初始化l默认初始值,声明时直接初始化,静态初始化器。 默认初始值,声明时直接初始化,静态初始化器l静态初始化器:静态初始化器:Java允许通过静态初始化器初始化静允许通过静态初始化器初始化静态数据成员静态初始化器语法:态数据成员静态初始化器语法:class A{static int i;static int j=10;static int k;static int m;static{ k=20;m=30;}}static{ ...//静态数据成员初始化语句静态数据成员初始化语句}694、实例数据成员与静态数据成员的对比、实例数据成员与静态数据成员的对比l类静态数据成员与实例数据成员二者区别:类静态数据成员与实例数据成员二者区别:((1)不管有多少类的实例,类的静态数据成员只有一份拷贝,)不管有多少类的实例,类的静态数据成员只有一份拷贝,即所有对象共享相同的静态数据成员;而每个实例对象都即所有对象共享相同的静态数据成员;而每个实例对象都有自己的实例数据成员有自己的实例数据成员 ((2)类的静态数据成员仅在类初次使用时创建、初始化以后)类的静态数据成员仅在类初次使用时创建、初始化以后不会再初始化了而每当创建类的对象时都为实例数据成不会再初始化了。 而每当创建类的对象时都为实例数据成员分配存储空间,并初始化员分配存储空间,并初始化3)实例数据成员只能通过对象来访,而类静态数据成员既)实例数据成员只能通过对象来访,而类静态数据成员既可以通过类名来访问,也可以通过对象来访问可以通过类名来访问,也可以通过对象来访问 70【【例例3-15】】实例数据成员与静态数据成员的对比实例数据成员与静态数据成员的对比class A{static int i;int j;A(){i=10; j=10;}void add(){i++; j++;}void display() {System.out.println("i="+i+",j="+j);}}public class Test{public static void main(String args[]){A a=new A();A b=new A();a.add();a.display();b.display();b.add();a.display();b.display();}}jjiab引用 对象 静态属性713.9.2 静态方法静态方法1、、 静态方法定义静态方法定义在方法声明前用在方法声明前用static修饰符修饰,则方法为静态方法。 如:修饰符修饰,则方法为静态方法如:class A{static void f ( ){ }}l注意:类的静态方法,属于整个类,而不针对特定对象,因此不能操作注意:类的静态方法,属于整个类,而不针对特定对象,因此不能操作与对象直接相关的内容:与对象直接相关的内容:((1)不能访问类的实例数据成员,不能调用类的实例方法不能访问类的实例数据成员,不能调用类的实例方法2)静态方法没有)静态方法没有this引用,因为引用,因为this代表当前对象,而静态方法并不代表当前对象,而静态方法并不与特定对象产生联系与特定对象产生联系3)静态方法可以做的是:访问类的静态数据成员,调用类的静态方)静态方法可以做的是:访问类的静态数据成员,调用类的静态方法当然除此以外可以定义方法内的局部变量,也可以声明并操作方法法当然除此以外可以定义方法内的局部变量,也可以声明并操作方法的参数722、静态方法的调用、静态方法的调用静态方法可以通过类名调用,也允许通过对象调用,也可以被类的其他静态方法可以通过类名调用,也允许通过对象调用,也可以被类的其他方法直接调用方法直接调用3、静态方法的应用、静态方法的应用静态方法的一个重要特点就是不用创建对象就可以调用。 这是一个至关静态方法的一个重要特点就是不用创建对象就可以调用这是一个至关重要的用途,有时候类中会有一些方法需要在没有对象时也能使用重要的用途,有时候类中会有一些方法需要在没有对象时也能使用如:应用程序执行的入口点如:应用程序执行的入口点main方法必须是静态的因为在其执行时,方法必须是静态的因为在其执行时,还没有任何对象被创建出来还没有任何对象被创建出来l静态方法常用于描述一些通用的算法静态方法常用于描述一些通用的算法l静态方法也常用于访问静态数据成员静态方法也常用于访问静态数据成员73【【例例3-16】】静态方法静态方法class A{int i=100;static void f(){System.out.println("hello");}void display() {System.out.println(i); f();}}public class Test{public static void main(String args[]){A.f();A a=new A();a.f();a.display();}}74【【例例3-17】】返回两个整数的较大值的静态方法返回两个整数的较大值的静态方法public class Test{static int max(int a,int b) {if ( a > b )return a;elsereturn b;} public static void main(String args[ ]) {int a=10,b=12,c=3,max;max=max(a,b);max=max(max,c);System.out.println(max);}}75class Count{int i=0;static int counter=0;static void add( ){counter++;}static void display( ){System.out.println(counter);}void addi( ){i++;}void displayi( ){System.out.println(i);}}public class Test{public static void main(String args[ ]){Count.display( );Count.add( );Count.display( );Count a=new Count( );a.add( );a.display( );a.addi( );a.displayi( );Count b=new Count( );b.add( );b.display( );b.addi( );b.displayi( );a.display( );}}763.10 final 修饰符修饰符lJava提供了提供了final修饰符,修饰符,final表示最终的。 表示最终的l这个修饰符可以用来修饰这个修饰符可以用来修饰l局部变量局部变量l数据成员数据成员l类类l方法方法771. final修饰局部变量修饰局部变量l终态局部变量,其特点是初始化其值以后就不能终态局部变量,其特点是初始化其值以后就不能再修改其值,相当于标识符常量再修改其值,相当于标识符常量 public class Test{public static void main(String args[ ]){final int i;i=10;i=11; //错错}}782. final修饰类的数据成员修饰类的数据成员l终态数据成员,其值在程序执行期间不能改变终态数据成员,其值在程序执行期间不能改变lfinal数据成员必须在声明变量时,或在构造数据成员必须在声明变量时,或在构造方法中初始化,以后在任何其他地方不能再修方法中初始化,以后在任何其他地方不能再修改它的值改它的值79class T{final int n = 10;final int m;T(int a) {m=a;n=20; //错错}void f(){n=21; m++; //错错}}class Test{public static void main(String args[ ] ){T t = new T(10);t.m = 100; //错错}}803. final修饰类的方法修饰类的方法lfinal修饰符可以修饰方法,将修饰符可以修饰方法,将final修饰符放于方法修饰符放于方法声明前。 声明前final修饰的方法为终态方法,其特点为此修饰的方法为终态方法,其特点为此方法不能被其子类覆盖方法不能被其子类覆盖4. final修饰类修饰类lfinal修饰符还可以直接修饰类,将修饰符还可以直接修饰类,将final修饰符放于修饰符放于类声明的前面用类声明的前面用final修饰的类为终态类,其特点修饰的类为终态类,其特点为此类不能被继承,为此类不能被继承,不能创建此类的子类不能创建此类的子类813.11 应用实例应用实例 1、对象之间的联系与对象之间的协作、对象之间的联系与对象之间的协作l对象之间的联系方式会体现在类的定义上,如前对象之间的联系方式会体现在类的定义上,如前面讲到的:引用类型做参数,引用类型做数据成面讲到的:引用类型做参数,引用类型做数据成员,引用类型做返回值,引用类型做局部变量员,引用类型做返回值,引用类型做局部变量这些途径能够使一个对象与其他对象联系起来这些途径能够使一个对象与其他对象联系起来l组成关系组成关系l关联关系关联关系82【【例例3-18】】假设一个公司有若干职员,若干办公室,职假设一个公司有若干职员,若干办公室,职员与办公室有关联,这个关联表示职员所在的办公地员与办公室有关联,这个关联表示职员所在的办公地点,程序希望通过职员能获得其办公地点的信息,并点,程序希望通过职员能获得其办公地点的信息,并能为职员调整办公室。 分别设计职员类和办公室类,能为职员调整办公室分别设计职员类和办公室类,通过在职员类中添加办公室类引用作为数据成员,表通过在职员类中添加办公室类引用作为数据成员,表示职员的办公地点示职员的办公地点83class Room{ String id; int personCount; int currentCount=0;Room(String id,int pc) {this.id=id; personCount=pc;}void addPerson(){ currentCount++;}void removePerson(){ currentCount--;}String getId(){ return id;}void display(){ System.out.print("房间号:房间号:"+id);System.out.print(",额定人员额定人员"+personCount+"名名");System.out.println(",目前人员目前人员"+currentCount+"名名");}}84class Employee{String name; Room room=null; Employee(String na){ name=na; }void setRoom(Room r){ if(room!=null)room.removePerson(); room=r; room.addPerson(); }void display(){ System.out.println("职员职员"+name+",工作地点工作地点"+room.getId());}}85public class Test{public static void main(String args[ ]){Employee a=new Employee("小张小张"); //字符串常量做参数字符串常量做参数Employee b=new Employee("小李小李");Employee c=new Employee("小马小马");Room r1=new Room("101",3);Room r2=new Room("102",4);a.setRoom(r1); //小张在小张在101b.setRoom(r1); //小李在小李在101c.setRoom(r2); //小马在小马在102a.display();b.display();c.display();r1.display();r2.display();c.setRoom(r1); //小马改在小马改在101c.display();r1.display();r2.display();}}86。









![2019版 人教版 高中语文 必修 上册《第一单元》大单元整体教学设计[2020课标]](http://img.jinchutou.com/static_www/Images/s.gif)


