JAVA程序设计教学第四章.ppt_第1页
已阅读1页,还剩92页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第4章 Java的类,2,本章主要讲述的内容,类的定义和使用; 方法的定义和使用; 实例变量和局部变量; 构造函数; 方法的覆盖和重载; 关键字this的用法;,继承的概念和应用; 组合与继承; 抽象方法和抽象类; 对象类型转换; 访问权限限制符:public、private、protected。,3,4.1 类与对象,在Java程序中,除原子类型的变量以外都是对象,连Java程序本身也不例外。 类是面向对象程序设计的基础,OO始终是围绕着对象的封装性、继承性和多态性展开讨论的。,4,4.1.1 类与对象的区别,类是一个抽象的概念,对象是一个具体的概念。 类是在一组对象的基础上,通过抽象和概括

2、获得的一个概念。 对象是由数据和方法紧密结合的一个封装体,具有信息隐藏的能力。 对象可以通过方法(函数)与其它对象进行通信,但并不知道这些方法的实现细节。,5,4.1.2 Java和C编程思想的区别,C是结构化的编程语言,以函数为编程单元,程序员把注意力集中在编写函数上。 Java是面向对象的编程语言,以类为编程单元,程序员的精力集中在对类的设计上。 对象将实例变量(instance variable)和对数据的操作(即方法)约束在一起,类似一个独立的程序,易于扩充,易于维护,代码可复用。,6,4.1.3 如何定义类,类是对象的模板,它定义了对象的结构和操作数据的方法。定义格式如下:,clas

3、s className extends superClassName type instance-vairbale1; return-type methodName1( parameter-list) method-body; ,7,4.1.3 如何定义类(续),系统类Object是整个类层次结构中的根。 类内定义的变量称为实例变量,函数称为方法; Java将类的定义和类的实现放在一起,便于系统维护。例如:,8,4.1.3 如何定义类(续),class point / Object类的子类 int x , y; void init(int a, int b )x=a; y=b; ,9,4.1.

4、4 对象和引用,对象是客观存在的变量,对象的引用就是对象的名字,例如:point p1; 创建对象:p1=new point( ); 一个对象可以有多个别名 ; 将一个变量设置为null,表明该变量不代表任何对象 : p1 = null ; 每个对象都有自己的变量,改变一个对象的实例变量并不影响到另外一个对象。例如:,class point / 程序4-1 int x , y; void init(int a, int b ) x=a; y=b; public class twoPoint public static void main(String args) point p1= new p

5、oint ( ), p2= new point ( ); p1.x=10;p1.y=20; p2.x=30;p2.y=40; System.out.println(x = + p1.x + y= +p1.y); System.out.println(x = + p2.x + y= +p2.y); ,11,4.2 方法,方法是一个功能模块 ,类似C中的函数; 方法和实例变量都必须定义在类内,方法是类的功能接口 ; 定义方法的原则:方法应当只执行单一的任务,并且方法名能有效地表达该任务; 方法的返回值类型、方法名和参数表共同称之为方法的特征。,12,4.2 方法(续),调用方法的格式:引用. 方法

6、名(参数表);,例如: point p1=new point( ),p2=new point( ); p1.init(10,20); /仅对p1对象的x和y进行赋值,13,4.3 实例变量和局部变量,Java中的变量分为两种:类内定义的实例变量,方法中定义的局部变量。 在同一个作用域内,不允许定义两个同名的局部变量。 局部变量可以掩盖实例变量。,class loc / 程序4-2 int x=1;/ 实例变量 void printLocVar( ) int x=25;/ 局部变量 System.out.println(n x is :+x); +x; System.out.println( x

7、 is :+x); void printInstanceVar( ) System.out.println(n x is :+x); x*=10; System.out.println(x is :+x); ,public class testInstanceVar / 程序的主类 public static void main(String args ) loc obj=new loc( ); int x=5;/ 局部变量 x System.out.println( x is :+x); obj.printLocVar( ); obj.printInstanceVar( ); System.

8、out.println( x is :+x); ,16,4.3 实例变量和局部变量(续),实例变量属于对象,它描述了对象的属性,随着对象的存在而存在; 局部变量是随着方法的调用而存在,一旦方法调用结束,局部变量也就消亡了。,17,4.4 构造函数,构造函数的功能是在创建对象时初始化对象的实例变量; 构造函数与类具有相同的名字; 构造函数没有返回值; 如果类中没有定义构造函数,编译器会自动创建一个缺省的、不带参数的构造函数。 构造函数是在对象创建之后,new操作完成前被调用的。,class point / 程序4-3 int x, y; point(int a, int b) x=a;y=b;

9、public class createPoint public static void main(String args ) point p= new point(10,20); System.out.println(p.x + +p.y); ,思考:无构造函数怎么办?,19,4.5 方法重载,方法重载是在一个类中定义二个或多个同名的方法,但方法的参数个数或类型不完全相同;例如:,class point int x, y; point(int a, int b) x=a;y=b; point( )x=-1;y=-1; ,20,注意以下两点,一旦定义了构造函数,Java就不能再调用系统缺省构造函

10、数; 方法重载的一个误区是靠返回值区别重载,即定义多个方法,它们的名称和形参类型完全相同,但返回值不同,这是不允许的。,21,4.6 关键字this,this指代对象 ,例如:,class IntVector / 程序4-6 int v ; boolean equals(IntVector other) if (this = other)return true; return false; class testIntVector public static void main(String args ) IntVector t1=new IntVector( ), t3=new IntVect

11、or( ), t2=t1; System.out.println(t1.equals(t2); System.out.println(t3.equals(t2); ,23,4.6 关键字this(续),this指代对象可以用于解决实例变量被局部变量屏蔽的问题。 例如:,class point int x , y; void init(int x, int y ) this.x=x; this.y=y; ,24,4.6 关键字this (续),Java中的级连调用,仍是指代当前对象的this。例如:,/ 程序4-7 import java.awt.*; import java.applet.*;

12、 class time private int hour, min, sec; time( ) setHour(0);setMin(0);setSec(0); time setHour(int h) hour=(h=0 ,time setMin(int m) min=(m=0 ,public class timeToString extends Applet private time t; public void init( ) t=new time( ); public void paint(Graphics g) t.setHour(18).setMin(30).setSec(20); g

13、.drawString( time:+t.tostring( ),25,45); ,28,4.6 关键字this (续),在构造函数内部使用this,它用于指代另外一个构造函数,但不能指代非构造函数。例如:,class point int x, y; point( )this(-1,-1); point(int a, int b) x=a;y=b; ,29,4.7 继承,继承是软件重用的一种形式 ,可以提高系统的性能; Java不支持多继承,但支持多接口; 子类的对象也是其超类的对象,反之未必; 继承具有传递性。,继承语法: class className extends superClass

14、Name 各实例变量和方法的定义 ,class point int x, y; point(int x, int y) this.x=x; this.y=y; point( ) this.x=0; this.y=0; class circle extends point int radius; circle(int r, int x, int y) radius=r; this.x=x; this.y=y; ,31,关键字super,构造函数是一种特殊的方法,子类不能继承超类的构造函数,但子类构造函数可以通过super调用超类的构造函数。 当创建子类对象时,首先执行超类构造函数,然后执行子类的

15、构造函数。例如:,class point / 程序4-8 int x, y; point(int x, int y) this.x=x; this.y=y; System.out.println(父类构造函数被调用!); class circle extends point int radius; circle(int r, int x, int y) super(x, y); radius=r; System.out.println(子类构造函数被调用!); ,public class testInherence public static void main(String args ) c

16、ircle c1; c1=new circle(1,1,1); ,34,再次讨论构造函数,若父类没有定义构造函数,那么对父类数据的初始化将采用系统缺省的构造函数;例如:,class point int x, y; class circle extends point int radius; circle(int r, int x, int y) this.x=x; this.y=y; radius=r; ,35,再次讨论构造函数(续),若父类定义有缺省构造函数,那么子类可根据自己的需要设置自己的构造函数。例如:,class point int x, y; point( ) this(0,0);

17、 point(int x, int y) this.x=x; this.y=y; class circle extends point / 注意子类的构造函数 int radius; circle(int r, int x, int y) radius=r; ,36,再次讨论构造函数(续),若父类定义的构造函数都是有参的,那么子类构造函数必须通过super调用父类构造函数,例如:,class point private int x, y; point(int x, int y) this.x=x; this.y=y; ,class circle extends point int radius

18、; circle(int r, int x, int y) super(x, y); radius=r; ,37,4.8 方法的覆盖,方法的覆盖发生在父类和子类之间,若子类中定义的某个方法的特征,与父类中定义的某个方法的特征完全一样,那么就说子类中的这个方法覆盖了父类对应的那个方法。,38,4.8.1 覆盖与重载的区别,重载可以出现在一个类中,也可以出现在父类与子类的继承关系中,并且重载方法的特征一定不完全相同。 覆盖特点:子类中的方法特征与父类定义的对应方法的特征完全一样。例如:,/ 程序4-9 class point int x, y; point( ) this(0,0); point(

19、int x, int y) this.x=x; this.y=y; double area( ) return 0; class circle extends point int radius; circle(int r, int x, int y)super(x, y); radius=r; double area( ) return Math.PI*radius*radius ; ,public class testOverWrite public static void main(String args ) circle c1; c1=new circle(1,1,1); System.

20、out.println(c1.area( ); ,41,4.8.2 方法的动态调用,Java的所有对象运行时都有一个类型标识(RTTI:Run-Time Type Identification),该标识记录了每个对象所属于的类。Java用此标识在运行时选择正确的方法。例如:,/ 程序4-11 class point int x, y; point( ) this(0,0); point(int x, int y) this.x=x; this.y=y; double area( ) return 0; class circle extends point int radius; circle(

21、int r, int x, int y) super(x, y); radius=r; double area( ) / 覆盖了父类的area方法 return Math.PI*radius*radius ; ,public class dynamicalCall public static void main(String args ) point p =new point(2,2), new circle(1,1,1) ; for(int i=0;ip.length;i+) System.out.print(“类名: ”+ pi.getClass( ).getName( ); System

22、.out.print(“父类:”+ pi.getClass( ).getsuperclass( ); System.out.println(“ 面积: ”+ pi.area( ); ,44,方法的动态调用小节,子类对象调用方法时(1) 子类检查是否具有同名和同参数类型的方法,若有调用该方法,否则继续执行。(2) 到父类中寻找同名和同参数类型的方法,若有调用该方法。若找不到,将产生编译错误。 对象决定自己到底该调用哪个方法,取决于该对象在继承链中的位置。,45,4.9 多态性不适合继承链中的实例变量,对象.方法:根据多态性调用; 对象.实例变量:根据对象的类型调用。即:多态性仅仅适用于方法的调用

23、,而不适合实例变量 。例如:,class Base/ 程序4-12 int x=1; void print( ) System.out.println(“当前类为 ”+ this.getClass( ).getName( ); System.out.println(对象的x= +this. x ); class Derived extends Base int x=2; void print( ) System.out.println(“当前类为 ”+ this.getClass( ).getName( ); System.out.println(对象的x= +this. x ); ,publ

24、ic class confusions public static void main(String args) Base obj=new Derived( ); obj.print( ); System.out.println(对象的x= +obj.x); ,下面是输出结果: 当前类为 Derived 对象的x= 2 对象的x= 1,48,4.10 finalize,Java的垃圾回收器具有自动回收垃圾的能力。 垃圾回收器是一个优先级比较低的线程,在系统空闲时运行。 在对象被回收之前,有时需要执行一些特殊的操作,例如保存文件、清除屏幕等,这时就要用Java的finalize方法。例如:,cl

25、ass point / 程序4-13 int x, y; point(int a, int b) x=a; y=b; System.out.println(point constructor:+getString( ); public void finalize( ) / 注意该方法 System.out.println(point finalizer:+getString( ); String getString( ) return x=+x+ y=+y; ,class circle extends point int radius; circle(int r, int a, int b)

26、super(a,b);radius=r; System.out.println(circle constructor:+getString( ); public void finalize( ) System.out.println(circle finalizer:+getString( ); String getString( ) return super.getString( )+ radius=+radius; ,public class testFinalize public static void main(String args ) point c1,c2; c1=new cir

27、cle(1,1,1); c2=new circle(2,2,2); c1=null; c2=null; System.gc( ); ,程序运行结果: point constructor: x=1 y=1 radius=0 circle constructor: x=1 y=1 radius=1 point constructor: x=2 y=2 radius=0 circle constructor: x=2 y=2 radius=2 circle finalizer : x=1 y=1 radius=1 circle finalizer : x=2 y=2 radius=2,52,4.11

28、 static,static修饰变量(与C中的不同); static修饰方法(与C中的不同);,53,4.11.1 static变量,static变量是指这样的成员变量:不管在程序运行中生成多少个该类的对象,它们都共享该变量。 即使没有创建对象,该变量仍然存在。因此,static变量又称为类变量。 定义格式为:static type variableName ; static变量和一般的实例变量不同,在构造函数中不能对它进行初始化。例如:,class point / 程序4-14 static int count; int x, y; static/ 静态初始化块 count=0; Syste

29、m.out.println(static variable is initialized !); point(int a, int b) count+; x=a; y=b; System.out.println(Call point constructor!); ,public class testStaticVariable public static void main(String args ) point c1=new point(0,0) ; System.out.println(There are + point.count + points); ,程序输出结果: static v

30、ariable is initialized ! Call point constructor! There are 1 points,56,4.11.2 static方法,static方法是类中的成员方法,它属于整个类,即使不创建任何对象,也可使用静态方法。 在子类中不能覆盖父类中定义的静态方法。 调用静态方法格式:类名.方法名(参数); 静态方法中只能出现静态变量和其它静态方法。并且还不能使用this和super。例如:,class point / 程序4-15 static int count;/ 定义静态变量 int x, y; static count=0; System.out.p

31、rintln(static variable is initialized !); point(int a, int b) count+; x=a; y=b; System.out.println(Call point constructor!); static int getCount( ) / 静态方法 return count; ,public class testStaticMethod public static void main(String args ) point c1=new point(0,0); point c2=new point(1,1); System.out.p

32、rintln(There are + point.getCount( ) + points); ,59,4.12 关键字final,在实例变量、局部变量和方法的形参定义之前加上final,那么这个变量值只能被引用,而不能修改。 final修饰的局部变量和实例变量必须给出初值,因为它修饰的变量代表一个常量。例如:,class Base / 程序4-16 final int x=1;/ 形式1:修饰实例变量 void print(final int y )/ 形式2:修饰参数 / y=0; / 错误 System.out.println(x+y); public class finalVariab

33、les public static void main(String args) final int var=100;/ 形式3:修饰局部变量 Base obj=new Base( ); obj.print(var); ,61,4.12.2 final方法,在方法定义前加上final,该方法就不能被子类覆盖,成为终极方法 ; 包含终极方法的类仍然可以被子类继承,子类虽然不能覆盖父类中的终极方法,但可以重载该方法。例如:,class Base final int x=1; final void print(int y ) / 父类中的final方法 System.out.println(x+y)

34、; class Derived extends Base void print( )/ 重载了父类中的print方法 System.out.println(x); ,63,4.12.3 final类,在一个类定义前加上final,意味着这个类就不能被其它类继承,成为终极类。 系统类基本上都是final类,如String类。 将class定义为final是为了杜绝继承,类中的方法自然都变成了终极方法。例如:,final class Base/ 声明为final类 final int x=1; void print(final int y ) System.out.println(x+y); /

35、错误:不能继承final 修饰的Base类 class Derived extends Base ,65,4.13 组合与继承,面向对象中的软件重用表现为两种形式:继承和对象组合。 设计这类程序的关键是构造函数:子类构造函数调用父类构造、成员对象的初始化。 例如:,class date/ 程序4-17 int year, mon,day; date(int y, int m, int d) year=y; mon=(m0 ,class employee/ 雇员类 long id; date birthday; employee(long no, int year, int mon, int d

36、ay) id=no; / 设置组合对象 birthday=new date(year,mon,day); String tostring( ) return id+ , +birthday.tostring( ); ,class manager extends employee / 经理类 double basePay; manager(long no, int y, int m, int d) super(no,y,m,d); / 调用父类构造函数 basePay=1000; String tostring( ) return basePay+ , +super.tostring( ); ,

37、public class compositionAndInherence public static void main(String args) manager boss; boss=new manager(1001,1971,11,5); System.out.println(boss.tostring( ); ,程序运行结果如下: 1000.0 , 1001 , 1971/11/5,70,4.14 抽象类和抽象方法,抽象方法:仅有方法特征,但没有代码; 抽象类:包含抽象方法的类。但是,不包含抽象方法的类也可以是抽象类。 抽象类的作用:提供一种适当的超类,子类通过继承实现父类中的抽象方法。

38、 抽象类不能用final修饰。 抽象类体现了多态性,通过继承可以从抽象类派生出具有相似操作的子类。例如:,71,/ 程序4-18 abstract class instrument abstract void play( );/ 抽象方法 / wind不是抽象类 class wind extends instrument void play( )System.out.println(wind play!); / percussion也是抽象类 class percussion extends instrument void play( ) System.out.println(percussi

39、on play!); ,/ stringed也不是抽象类 class stringed extends instrument void play( ) System.out.println(stringed play!); class woodWind extends wind / 覆盖父类中的play方法 void play( )System.out.println(woodWind play!); class brass extends wind / 覆盖了父类中的play方法 void play( )System.out.println(brass play!); ,public cla

40、ss music static void tuneAll( instrument e ) for(int i=0;ie.length;i+) ei.play( ); public static void main(String args) instrument orchestra = new instrument5; int i=0; orchestrai+=new wind( ); orchestrai+=new percussion( ); orchestrai+=new stringed( ); orchestrai+=new woodWind( ); orchestrai+=new b

41、rass( ); tuneAll(orchestra); ,程序运行结果: wind play ! percussion play! stringed play! woodWind play! brass play!,76,4.15 对象的类型转换,类型向上转换(upcasting); 类型向下转换(downcasting)。,77,4.15.1 向上类型转换,从子类向父类转换,在继承图中是向上移动,通常称为向上类型转换。 类型向上转换是安全的,因为这是从特殊类型到通用类型的转换。 进行向上类型转换时,出现的唯一问题是可能丢失子类中定义的方法和变量。例如:,/ 程序4-19 class poi

42、nt int x, y; point(int x, int y) this.x=x; this.y=y; int getX( ) return x; class circle extends point int radius; circle(int r, int x, int y) super(x, y); radius=r; double area( ) return Math.PI*radius*radius; ,public class testUpCasting public static void main(String args) circle c=new circle(1,1,1

43、); point p=c;/ 注意:p和c的类型不同 System.out.println(p.getX( ); ,80,4.15.2 向下类型转换,从父类向子类转换,在继承图中是向下移动,称为向下类型转换。 类型向下转换是不安全的,因为这是从一般类型到特殊类型的转换。例如:,public static void main(String args) point p=new point(1,1); circle c; if( p instanceof circle) /判断能否进行类型转换 c=(circle)p; System.out.println(c.area( ); else/ 出错处理 System.out.println(can not downCasting); ,82,4.16 访问权限限制,Java提供的访问权限修饰符有四个,即public、private、protected和友元; 修饰符要置于每个类成员的定义之前,且仅能控制它所修饰的那个成员 。,83,4.16.1 友员,缺省修饰符的情况就是友员。友员修饰符意味着同一个目录(包)中的所有类都可以访问这种类型的成员。 friendly不属于Java关键字,是C+的一个关键字。 例如:,public class Base / 该类位于Base.java文件中 int friend_data

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论