资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,返回,第,4,章,Java,程序结构,Java,语言是一种纯面向对象的程序设计语言,它的核心概念是类和对象,它的程序是基于类和对象建造的,程序中类的结构决定了程序的结构。这一章较深入系统地介绍,Java,程序的结构,介绍组成,Java,程序的类之间的关系。,Java,程序结构,类层次结构,对象的使用与对象间通信,多态性,接口与包,访问控制与修饰符,类层次结构,继承的概念,继承的描述,类的继承规则,变量的隐藏,继承的概念,在日常生活中,我们常用“是一种(,is-a,)”关系来组织与表达知识,从而将知识组织成一种有层次、可分类的结构。面向对象程序设计方法将,is-a,关系引入到程序设计领域,用于描述类与类之间的关系,称之为,继承,。,多态性,同一运算或方法(如“,+”,)对不同类型的对象(如整型数,或字符串)有不同的语义解释。这种在程序中同一方法对不同类型的对象有不同解释的现象称为,多态性,多态性与继承是密不可分的。通常,两类对象都有共同的父类,在父类中定义的方法在这两个子类中分别有不同的实现,超类,与,子类,我们在声明类,A,时,指明类,A,继承了类,B,(类,B,是一个已定义了的类),则类,A,通常就拥有了类,B,的成员变量和方法。此时,类,B,称为类,A,的直接,超类,(,superclass,),超类也称为父类或基类;类,A,称为类,B,的直接,子类,(,subclass,),子类也称为派生类,继承的描述,Java,语言中,声明类首部的格式如下:,类的修饰符,class,类名,extends,超类名,implement,接口名表,其中“,extends,超类名,”部分就是用来描述继承的,这里,超类,名指明所声明类的直接超类,继承描述的演示,class Car /,声明,Car,类,int,car_number,;,void,set_number(int,car_num,),car_number,=,car_num,;,void,show_number,(),System.out.println,(,我的车号是:,+,car_number,);,class,TrashCar,extends Car /,声明,TrashCar,类,它继承,Car,类,int,capacipy,;,void,set_capacity(int,trash_car_capacipy,),capacipy,=,trash_car_capacipy,;,void,show_capacity,(),System.out.println,(,我的容量是:,+,capacipy,+);,类的继承规则,直接子类继承那些被声明为,public,或,protected,的直接超类成员(包括成员变量和成员方法,下同),直接子类继承那些未被存取权限修饰符修饰的直接超类成员,只要该子类与该超类在同一个包中,如果直接子类声明了一个与直接超类中的成员同名的成员,则该子类不继承该超类中的该同名成员,直接子类不继承被修饰为,private,的直接超类的成员,变量的隐藏,直接子类声明了一个与其直接超类的成员变量同名的成员变量,则称该超类的该成员变量在该直接子类中被,隐藏,,关键字,this,和,super,分别用来指明直接子类和其直接超类中同名的成员变量,当超类的成员变量、子类的成员变量和类中方法使用的局部变量三者同名,或其中的两者同名时,可以使用关键字,this,和,super,来指定所要使用的变量,this,和,super,区别同名变量的演示,class A,int,x,;,/,类,A,中声明了成员变量,x,class B extends A/,类,B,继承类,A,,也继承了类,A,的成员变量,x,int,x;/,类,B,中又声明了成员变量,x,void m(),int,x;/,方法,m,声明了自己的局部变量,x,super.x,=2;/,super.x,是其所在类的父类即类,A,的,x,this.x,=1;/,this.x,是其所在类即类,B,的,x,x=100;/x,是方法本身的局部变量,x,对象的使用与对象间通信,对象的创建,对象的使用,对象间的通信(消息)与实例方法的调用,对象的创建,Java,中,类是某一类对象的共同特征(属性、行为)的描述,即类中含有某一类对象具有,哪些属性,、,哪些行为,的信息。而由类创建的多个对象都具有类所定义的那些属性和行为。但是,由同一个类所创建的不同对象的同一个属性的值可能不同,对象的生命周期,对象和现实生活中的事物一样,有它的产生、发展和消亡的过程,在,Java,中分别称之为对象的创建、使用和释放,这一过程称为,对象的生命周期,定义一个学生类,class Student /Student,是学生类名,/,定义成员变量,private,int,sNumber,;/,学号,private String,sName,;/,姓名,private String,sClass,;/,班号。以下是,定义成员方法,void,setSNumber(int,xNumber,)/,成员方法,setSNumber,sNumber,=,xNumber,;,int,getSNumber,()/,成员方法,getSNumber,return,sNumber,;,void,setSName(String,xName,)/,成员方法,setSName,sName,=,xName,;,String,getSName,()/,成员方法,getSName,return,sName,;,void,setSClass(String,xClass,)/,成员方法,setSClass,sClass,=,xClass,;,String,getSClass,();/,成员方法,getSClass,return,sClass,;,创建对象过程,对象的声明,对象的实例化,对象的初始化,对象的声明,对象声明的语法形式为,:,类名,对象名,;,该语句从指定的类创建对象。,对象的实例化和初始化,必须给一个对象分配相应的存储空间,才能使用它。在声明一个对象时,并没有为该对象分配存储空间。对象的实例化完成对象的空间分配,对象实例化是通过,new,操作完成。构造方法的调用则确定了对象的初始状态,这一过程就是初始化,对象创建过程的演示,class Course /Course,是课程类名,/,定义成员变量,private,int,cNumber,;/,课程编号,private String,cName,;/,课程名,private,int,cUnit,;/,学分数,/,定义成员方法,void,setCNumber(int,xNumber,)/,成员方法,setCNumber,cNumber,=,xNumber,;,int,getCNumber,()/,成员方法,getCNumber,return,cNumber,;,void,setCName(String,xName,)/,成员方法,setCName,cName,=,xName,;,String,getCName,()/,成员方法,getCName,return,cName,;,void,setCUnit(int,xUnit,)/,成员方法,setCUnit,cUnit,=,xUnit,;,int,getCUnit,()/,成员方法,getCUnit,return,cUnit,;,public class InitialDemo1,public static void,main(String,args,),Course cs1=new Course();/,声明一个,Course,对象,cs1,System.out.println(cs1.getCNumber();/,输出初始值,cNumber,System.out.println(cs1.getCName();/,输出初始值,cName,System.out.println(cs1.getCUnit();/,输出初始值,cUnit,演示对象的初始化,class Course /Course,是类名,/,定义成员变量,int,cNumber,=1;/,课程编号,String,cName,=”Wang”;/,课程名,int,cUnit,=2;/,学分数,public class InitialDemo2,public static void,main(String,args,),Course cs1=new Course();/,声明一个,Course,对象,cs1,System.out.println(cs1.cNumber);/,输出初始值,cNumber,System.out.println(cs1.cName);/,输出初始值,cName,System.out.println(cs1.cUnit);/,输出初始值,cUnit,演示使用构造方法进行初始化,class Course /Course,是类名,/,定义成员变量,int,cNumber,=1;,String,cName,;,int,cUnit,=2;,/,构造方法,Course(String Name,int,Unit),cName,=Name;,cUnit,=Unit;,public class InitialDemo3,public static void,main(String,args,),Course cs1=new Course(“Zhang”,6);/,使用类中声明的构造方法,/,声明一个,Course,对象,cs1,System.out.println(cs1.cNumber);,System.out.println(cs1.cName);,System.out.println(cs1.cUnit);,演示由子类创建对象的过程,class A,int,x=1;,int,y=1;,A(int,x1,int y1),x=x1;,y=y1;,class B extends A,int,x=2;,float z;,B(int,xx,int,yy,),super(0,0);/,子类的构造方法中先调用超类的构造方法,否则,Java,调用默认的构造方法,A(),this.x,=xx;,this.y,=,yy,;,public class,EtndsDemo,public static void,main(String,args,),B b1=new B(1,2);,System.out.println(b1.x);,System.out.println(b1.y);,System.out.println(b1.z);,对象的使用,引用对象的成员变量,调用对象的成员方法,对象作数组元素,对象作类的成员变量,引用对象的成员变量,引用对象成员变量的语法形式为:,对象名,.,成员变量名,;,例:,Rectangle,类的声明,class Rectangle,int,width,;,int,height,;,Rectangle()/Rectangle,类的构造方法,width=20,;,height=30,;,静态变量和实例变量,类,myclass,int,Var1;,static,int,Var2;,对象,myobject1,Var1,Var2,对象,myobject2,Var1,Var2,myobject1.Var2,myobject2.Var2,myobject1.Var1,myobject2.Var1,静态变量,实例变量,调用对象的成员方法,如前所述,调用对象成员方法的语法形式为:,对象名,.,成员方法名,(,实际参数表,);,其中:,对象名,指定所使用的对象;,成员方法名,指定所要调用的成员方法;,实际参数表,由,0,个或多个表达式构成,表达式之间用逗号“,”分隔,调用对象方法参数传递过程演示,class MethodDemo1,/,实现两个形式参数,x,、,y,的相加,其和以方法返回值的形式传回,float,add(float,x,float y),float z;,z =x+y;,return z;,public class CallMethodDemo1,public static void,main(String,args,),float result;,methodDemo1,addCall,=new methodDemo1();,result=,addCall.add,(3,5);/,调用对象,addCall,的,add,方法,计算,3+5,System.out.println(result,);/result,的值为,3+5,说明实例,本例中类,MethodDemo1,给出一个实现两,float,型数相加的方法。方法的参数,x,、,y,是参与加法的操作数,相加的结果存于局部变量,z,中,,return,语句指明,z,的值即是方法的返回值。类,CallMethodDemo1,的,add,对象调用了类,MethodDemo1,的方法,add,,实参为整型,3,和,5,演示方法的一种用法,class Fact,float fact(,int,n)/,定义计算,n,!的方法,int,i;,float x=1;,for(i,=1;i,n;i,+),x=x*i;,return x;,public class MethodCallDemo2,public static void main(String,args,),Fact x=new Fact();,System.out.println(x.fact(10);/,计算,10,!,System.out.println(x.fact(15);/,计算,15,!,演示静态方法的用法,class Fact,static float fact(,int,n)/,将方法,fact,声名为静态方法,int,i;,float x=1;,for(i,=1;i,n;i,+),x=x*i;,return x;,public class MethodCallDemo5,public static void main(String,args,),System.out.println(Fact.fact(10);/,直接用类名,.,方法名调用静态方法,System.out.println(Fact.fact(15);,演示数组作为方法的参数,Java,中数组是作为对象来处理的,class methodDemo5,float,findMax(float,arr,)/,形式参数,arr,是数组,int,i;,float temp;,temp=arr0;,for(i,=1;itemp)temp=,arri,;,return temp;,public class MethodCallDemo6,public static void main(String,args,),float max;,float x =1,2,3,4,5;,methodDemo5 y=new methodDemo5();,max=,y.findMax(x,);/,实参,x,是数组,数组调用的返回值为,5.0,System.out.println(max,);,对象作数组元素,对象也可以作数组元素,当对象作数组元素时,其数组称为对象的数组。创建对象的数组时,首先对数组初始化,然后对数组的每个元素初始化,对象作数组元素用法的演示,class node,private,int,data;,private node next;,void,setData(int,x),data=x;,int,getData,(),return data;,node,getNext,(),return next;,void,setNext(node,x),next=x;,public class,ObjAsArrayElementDemo,public static void main(String,args,),/,创建,3,个结点,node x =new node3;/,创建元素为,node,型对象的数组并初始化数组,int,i;,for(i,=0;i,x.length;i,+)/,初始化数组元素,对象,xi,=new node();/,给结点的,data,赋值,并组成链表,for(i,=0;i,x.length;i,+),xi.setData(i,);,if(i,x.length-1)xi.setNext(xi+1);,/,利用,start,依次输出链表各结点的值,node start=new node();,start=x0;/,指向链表的第,1,个结点,System.out.println(start.getData,();/,输出,x0.data,while(start.getNext,()!=null),start=,start.getNext,();/,指向下一结点,System.out.println(start.getData,();/,输出,xi.data,对象作类的成员变量,class date,String,yy,;/,年,String mm;/,月,String,dd,;/,日,date(String,xyy,String,xmm,String,xdd,)/date,构造方法,yy,=,xyy,;mm=,xmm,;,dd,=,xdd,;,class Student,private,int,idNumber,height;/,学号、身高,private char sex;/,性别,date birthday;/,出生日期,birthday,是对象,/Student,构造方法,Student(int,id,int,h,char s,String,xyy,String,xmm,String,xdd,),idNumber,=id;,height =h;,sex =s;/,调用,date,构造方法,birthday=new,date(xyy,xmm,xdd,);,int,getHeight,()return height;,int,getSex,()return sex;,void show()/,输出学号,身高,性别,出生年份,System.out.println,();,System.out.print(/t+idNumber,);,System.out.print,(/,t+height,);,System.out.print,(/,t+sex,);,System.out.println(/t+birthday.yy,);,public class,UseStudent,public static void,main(String,args)throws,java.io.IOException,int,sum =0;,double,ave,;,Student a =new Student 3;/,创建对象的数组,数组元素初始化,a0 =new Student(100001,169,女,1976,06,12);,a1 =new Student(100002,155,女,1976,02,03);,a2 =new Student(100003,175,男,1976,05,25);/,求平均身高,for(,int,i=0;i,a.length,;i+),sum=,sum+a,i.getHeight,();,ave,=sum/3.0;/,输出超过平均身高的女生学号与身高,System.out.println,(,超过平均身高的女生学号与身高为,);,for(,int,i=0;i =,ave,)&(a,i.getSex,()=,女,),a,i.show,();,对象间的通信(消息)与实例方法的调用,消息是一个对象发送给另一对象的信息,用来驱动接受这一消息的对象的某个行为。,消息由三部分组成:接受消息的对象、对象中描述某一行为的方法以及这一方法所需要的参数。,这些问题包括对象作方法的参数、作方法的返回值、作数组元素以及作类的成员变量。,对象作方法的参数,当方法的参数时类类型时,方法的实参就是一个对象,这就是对象作方法的参数的情形。与基本数据类型的变量作方法参数的情形不同,在基本数据类型的变量作方法参数的情形下,进行方法调用时的语义动作,是将实参的值传递给相应的形参。,对象作方法参数的演示,class,objPara,/,定义对象作为参数的类,float temp;/,用成员变量,temp,传递参数值,class methodDemo4,void,add(float,x,float y,objPara,z)/,对象,z,作为方法,add,的参数,z.temp,=,x+y,;/,方法体对对象,z,进行操作,可以改变,z,的值,void callAdd2(float,m,float,n),objPara,k=new,objPara,();,add(,m,n,k,);/,向方法,add,发消息,将参数,m,n,的值分别传递给,x,y,并将,k,的,/,存储地址值传送给,z,,然后执行方法,add,的方法体,计算,x+y,,,/,计算结果通过,k,传回,callAdd,方法,System.out.print(m+n,+=+,k.temp,);/,k.temp,的值即为,m+n,public class MethodCallDemo7,public static void main(String,args,),objPara,x=new,objPara,();,methodDemo4 y=new methodDemo4();,System.out.println(x.temp);/x.temp,值为,0.0,y.add(1,2,x);/,调用对象,y,的,add,方法,计算结果存于对象,x,的,temp,变量中,System.out.println(x.temp,);/,x.temp,值为,3.0,y.callAdd2(1,2);/,输出,1+2,的结果,对象作方法的返回值,class node,private,int,data;,private node next;/,成员变量,next,是,node,类型,而,node,是正在声明的类类型,void,setData(int,x),data=x;,int,getData,(),return data;,node,getNext,()/,此方法的返回值类型是类类型,return next;,void,setNext(node,x),next=x;,public class,ObjAsRetValDemo,public static void main(String,args,),/,创建,3,个结点,node x1=new node();,node x2=new node();,node x3=new node();/,给结点的,data,赋值,x1.setData(1);,x2.setData(2);,x3.setData(3);/,把,3,个结点组成链表,x1.setNext(x2);x2.setNext(x3);/,利用,start,依次输出链表各结点的值,node start=new node();,start=x1;/,指向结点,x1,System.out.println(start.getData,();/,输出,x1.data,start=,start.getNext,();/,指向下一结点,x2,System.out.println(start.getData,();/,输出,x2.data,start=,start.getNext,();/,指向下一结点,x3,System.out.println(start.getData,();/,输出,x3.data,多态性,方法的重构与重载,方法的动态调用,抽象类,多态性,多态性,,就是程序中同一操作在不同的环境中有不同语义解释的现象。和继承机制一样,多态性是面向对象方法的一大特色,它提供了使同一程序有很强的适应不同环境的能力的描述机制。,方法的重构与重载,在直接子类中定义的某个方法与其直接超类的某个方法有相同的名称和参数,则称该子类,重构,(,Overriding,)了该超类的该方法,重构也称为覆盖,在同一个类中定义了多个同名的方法,它们或有不同的形参个数或有不同的形参类型,则称该方法被,重载,(,Overloading,),方法重构的演示,class Father,void speak()/,超类定义的,speak,方法,System.out.println(I,am Father,!,);,class Son extends Father,void speak()/,子类重构的,speak,方法,System.out.println(I,am Son,!,);,方法重构的演示,class Father,void speak()/,超类定义的,speak,方法,System.out.println(I,am Father,!,);,class,DemoThisSuper,extends Father,void speak()/,子类重构的,speak,方法,System.out.println(I,am Son,!,);,void,demThisSuper,(),super.speak,();/,调用超类,Father,的,speak,方法,this.speak,();/,调用子类,DemoThisSuper,重构的,speak,方法,class MethodCallDemo4,public static void main(String,args,),Father x=new Father();,DemoThisSuper,y=new,DemoThisSuper,();,x.speak,();,/,执行方法体,System.out.println(I,am Father,!,);,y.speak();,/,执行方法体,System.out.println(I,am Son,!,);,y.,demThisSuper,();,/,super.speak,(),执行方法体,System.out.println(I,am Father,!,);,/,this.speak,(),执行方法体,System.out.println(I,am Son,!,);,演示方法的重载,class,Demoverload,int,add(int,x,int,y),return,x+y,;,double,add(double,x,double,y),return,x+y,;,class MethodCallDemo3,public static void main(String,args,),Demoverload,x=new,Demoverload,();,int,im,=1,in=2;,double fm=1.0,fn=2.0;,System.out.println(x.add(im,in,);/,调用时,匹配整型加方法,int,add(int,x,int,y),System.out.println(x.add(fm,fn,);/,调用时,匹配单精度型加方法,/double,add(double,x,double,y),方法重构的规定,子类重构父类方法时,子类方法的返回类型应当与被重构方法的相同,子类不能重构父类的,final,和,private,方法,子类不能用实例方法去重构父类的,static,方法。子类的,static,方法可重构父类的,static,方法,但不能重构父类的实例方法,子类方法重构父类方法时,子类方法的访问权限修饰词不能严于父类方法的访问权限修饰词,子类若要引用父类中的被重构方法,应使用“,super,方法名,”的方式,方法的动态调用,class Location/,位置类,int,x,y,;/,位置的坐标,Location(int,locX,int,locY,)x=,locX,;y=,locY,;,void show(),System.out.print(+x+,+y,+);,class Point extends Location/,点类,boolean,visible;/,可见性,Point(int,pointX,int,pointY,boolean,trueOrFalse,),super(pointX,pointY,);/,调用超类的构造方法,visible=,trueOrFalse,;,void,moveTo(int,newX,int,newY,)/,方法,-,移动到新位置,x=,newX,;y=,newY,;,class Circle extends Point/,圆类,int,r;/r,存放半径,Circle(int,centX,int,centY,int,radius,boolean,tureOrFalse,),super(centX,centY,tureOrFalse,);,r=radius;,void,expand(int,delta)r =,r+delta,;/,方法,-,扩展,void,contract(int,delta)r =rdelta;/,方法,-,收缩,void show(),System.out.print(t,圆心位于,);,super.show,();,System.out.print(t,半径为,+r);,if(visible),System.out.println(t,此圆发亮,);,else,System.out.println(t,此圆不发亮,);,class,TestPointCircle,public static void,main(String,args,),Point p =new Point(200,200,false);,System.out.print(t,点,p,的位置是,);,p.show,();/,调用超类,Location,的,show,方法,System.out.println,();,Circle c =new Circle(100,100,20,true);,c.show,();/,调用,Circle,类的,show,方法,c.moveTo(300,400);,c.expand(40);,c.show,();,说明,子类对象的引用可以赋给超类对象的引用;方法形参为某类对象时,可用其子类对象作实参。当子类对象引用赋给父类对象引用后,父类对象引用引用的是子类实例,用这个父类引用来引用子类实例成员(变量与方法)时只能引用与父类成员同名的那些成员。若成员变量出现隐藏,引用的是父类变量,若成员方法出现重构,引用的是子类的方法。,方法动态调用的演示,class,TwoDimension,void show(),class Point extends,TwoDimension,private,int,x,y;,Point(int,px,int,py,)x=,px,;y=,py,;,void show()/,重构了超类的,show,方法,输出点的位置,System.out.println,(,点的位置是,(+,x+,+y,+);,class Line extends,TwoDimension,private,int,x1,y1,x2,y2;,Line(int,px,int,py,int,qx,int,qy,),x1=,px,;y1=,py,;x2=,qx,;y2=,qy,;,void show()/,重构了超类的方法,输出线段两端位置,方法体语句略,class Circle extends,TwoDimension,private,int,cX,cY,radius;,Circle(int,x,int,y,int,r),cX,=x;,cY,=y;radius=r;,void show()/,重构了超类的方法,输出圆心坐标及半径,方法体语句略,class,UseTwoDimension,static void,showParameter(TwoDimension,plc),plc.show,();,public static void,main(String,args,),Point p =new Point(10,10);,Line l =new Line(0,20,100,20);,Circle c =new Circle(100,100,50);,/,p,l,c,均是,TwoDimension,类的子类类型,充当,showParameter,方法的实参,/,将子类对象引用赋给超类对象引用,showParameter,(p);/,执行,p.show,(),showParameter,(l);/,执行,l.show,(),showParameter,(c);/,执行,c.show,(),抽象类,使用修饰符,abstract,对类加以修饰,这个类就是,抽象类,(,abstract class,),抽象类不能被实例化。通常,抽象类中含有抽象方法,抽象方法是指只给出方法声明但没有方法体的方法。子类在继承抽象类时,,必须,重构其父类的抽象方法,给出具体的定义。,演示抽象类及其用法,abstract class Figure/,声明抽象类,Figure,double,x,y,;,void,set_size(double,size1,double size2),x=size1;,y=size2;,/,声明抽象方法,get_area,,它没有方法体,abstract double,get_area,();,class Triangle extends Figure/Triangle,继承抽象类,Figure,double,get_area,()/,重构其超类的抽象方法,get_area,(),return(x,*y/2);/,三角形面积,=,底*高,/2,class Rectangle extends Figure/Rectangle,继承抽象类,Figure,double,get_area,()/,重构其超类的抽象方法,get_area,(),return(x,*y);/,矩形面积,=,长*宽,接口与包,接口,包,接口,接口,(,interface,)是一个协定,它定义了一组行为的界面,但没有定义行为的具体实现过程。,任何一个类都可以实现一个接口。,所谓一个类实现一个接口,是指这个类给出这个接口的,所有,行为的具体实现过程。,从语法上看,接口由接口首部和接口体组成。接口首部给出接口名,如果存在接口的继承关系,也要在接口首部中给出。接口体主要是一组方法首部的说明,接口体中也可以声明一些常量。,接口声明、实现和使用的演示,/,声明接口,Figure,interface Figure/,接口首部,,interface,是关键字,,Figure,是接口名,/,接口体,void,set_size(double,size1,double size2);/,方法首部给出行为的界面,double,get_area,();,/,接口声明结束,class Triangle implements Figure/Triangle,实现接口,Figure,,,implements,是关键字,double,x,y,;,/,实现接口的方法,给出所实现接口的所有方法首部的方法体,public void,set_size(double,size1,double size2),x=size1;,y=size2;,public double,get_area,(),return(x,*y/2);/,三角形面积,=,底*高,/2,class Rectangle implements Figure/Rectangle,实现接口,Figure,double,x,y,;
展开阅读全文