java面向对象高级.ppt
面向对象的高级程序设计面向对象的高级程序设计伍淳华伍淳华北京邮电大学计算机学院北京邮电大学计算机学院面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类l所有类都是所有类都是Object的子类;的子类;Object Object objobj=new=new BackAccountBackAccount();();Object Object objobj=new=new String(“HelloString(“Hello”);”);2面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类lequals方法方法ltoString方法方法lclone方法方法在自己编写的类中,最好重写这些方法!在自己编写的类中,最好重写这些方法!3面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vequals方法方法public boolean equals(Object obj)return(this=obj);判断两个对象是否具有相同的引用判断两个对象是否具有相同的引用4面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vequals方法方法 class BankAccount public boolean equals(Object obj)BankAccount other=(BankAccount)obj;return(accountNumber=other.accountNumber&balance=other.balance)5面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vequals方法方法 class BankAccount public boolean equals(Object obj)if(this=obj)return true;if(obj=null)return false;if(getClass()!=obj.getClass()return false;BankAccount other=(BankAccount)obj;return(accountNumber=other.accountNumber&balance=other.balance)6面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类v子类中实现子类中实现equals方法方法l 首先调用超类的首先调用超类的equals,如果未通过测试,如果未通过测试,对象就不可能相等;对象就不可能相等;l如果超类中的域都相等,就比较子类中的实如果超类中的域都相等,就比较子类中的实例域;例域;7面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类v子类中实现子类中实现equals方法方法class SavingAccount extends BankAccount public boolean equals(Object obj)if(!super.equals(obj)return false;SavingAccount other=obj;return/比较比较SavingAccount中的成员变量中的成员变量8面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vJava语言规范要求语言规范要求equals方法具有下面的特性方法具有下面的特性1)自反性自反性:对于任何非空引用对于任何非空引用x,x.equals(x)应该返回应该返回true;2)对称性对称性:对于任何引用对于任何引用x和和y,如果如果x.equals(y)返回返回true,那么那么y.equals(x)也应该返回也应该返回true;3)传递性传递性:对于任何引用对于任何引用x,y,z,如果如果x.equals(y)返回返回true,y.equals(z)返回返回true,那么那么x.equals(z)也应该返也应该返回回true;4)一致性一致性:如果如果x和和y引用的对象没有发生变化引用的对象没有发生变化,那么反复那么反复调用调用x.equals(y)应该返回同样的结果应该返回同样的结果;5)对于任意非空引用对于任意非空引用x,x.equals(null)应该返回应该返回false;9面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类v注意注意:class BankAccount public boolean equals(BankAccount obj)if(this=obj)return true;if(obj=null)return false;if(getClass()!=obj.getClass()return false;return(accountNumber=obj.accountNumber&balance=obj.balance)10面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类v注意注意:class BankAccount public boolean equals(Object obj)if(this=obj)return true;if(obj=null)return false;if(!(obj instanceof BankAccount)return false;BankAccout other=(BankAccount)obj;return(accountNumber=other.accountNumber&balance=other.balance)11面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类v注意注意:l如果子类能够拥有自己的相等概念如果子类能够拥有自己的相等概念,那么对称那么对称性需求将强制采用性需求将强制采用getClass进行检测进行检测;l如果由超类决定相等的概念如果由超类决定相等的概念,则可以使用则可以使用instanceof进行检测进行检测,这样可以在不同子类的这样可以在不同子类的对象之间进行相等的比较对象之间进行相等的比较.12面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vhashCode方法方法lhasCode方法返回一个整型数值方法返回一个整型数值,并合理地组合实例并合理地组合实例域的散列码域的散列码,以便能够让各个不同的对象产生的散列以便能够让各个不同的对象产生的散列码更加均匀码更加均匀;l如果如果x.equals(y)返回返回true,那么那么x.hashCode()就必须就必须与与y.hashCode()具有相同的值具有相同的值;l如果重新定义如果重新定义equals方法方法,就必须重新定义就必须重新定义hashCde方法方法;lObject类的类的hashCode()方法返回对象的存储地址方法返回对象的存储地址;13面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vhashCode方法方法class BankAccountpublic int hashCode()return 7*Integer(accountNumber).hashCode()+11*Double(balance).hashCode();14面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vtoString方法方法l 返回对象的字符串表示返回对象的字符串表示;lObject类中默认返回对象所属的类名和散列类中默认返回对象所属的类名和散列码码.System.out.println(System.out);输出输出:java.io.PrintStreama90653 15面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vtoString方法方法l 重写重写toString方法一般遵循的格式为方法一般遵循的格式为:类名类名成员变量值成员变量值 java.awt.Pointx=20,y=20lBankAccout中的中的toString函数可改写为函数可改写为:public String toString()retrun“BankAccoutbalance=“+balance+”,accountNumber=“+accountNumber+”;16面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vtoString方法方法public String toString()retrun getClass.getName()+”balance=“+balance+”,accountNumber=“+accountNumber+”;17面向对象高级程序设计面向对象高级程序设计继承继承objectobject类类vtoString方法方法class SavingAccount extends BankAccountpublic String toString()retrun super.toString()+”interest=“+interest+”;18面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用Eg:DataSet19面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用 如果想计算一组如果想计算一组BankAccount对象中余对象中余额的最大值和平均值?额的最大值和平均值?20面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用 publicclassDataSet.publicvoidadd(BankAccountx)sum=sum+x.getBalance();if(count=0|maximum.getBalance()x.getBalance()maximum=x;count+;publicBankAccountgetMaximum()returnmaximum;privatedoublesum;privateBankAccountmaximum;privateintcount;21面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用 publicclassDataSet.publicvoidadd(Studentx)sum=sum+x.getScore();if(count=0|maximum.getScore()x.getBalance()maximum=x;count+;publicStudentgetMaximum()returnmaximum;privatedoublesum;privateStudentmaximum;privateintcount;22面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用X的数据类型;的数据类型;如果每个对象实现一个如果每个对象实现一个getMeasure方法来提供测量的方法来提供测量的内容,就可实现一个可重用的内容,就可实现一个可重用的DataSet,以,以add()方法为方法为例:例:sum=sum+x.getMeasure();if(count=0|maximum.getMeasure()x.getMeasure()maximum=x;count+;X的数据类型应该是什么?的数据类型应该是什么?-X的数据类型可以是任意实现了的数据类型可以是任意实现了getMeasure()的类。的类。23面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用接口可用来规范类的行为接口可用来规范类的行为public interface Measurabledouble getMeasure();DataSet可以返回一组对象中值最大的那个对象,并计算出这一组对象的平均值,但要求对象所属的类必须实现了Measurable接口。24面向对象高级程序设计面向对象高级程序设计接口接口v接口接口代码重用代码重用接口可用来规范类的行为接口可用来规范类的行为public interface Measurabledouble getMeasure();DataSet可以返回一组对象中值最大的那个对象,并计算出这一组对象的平均值,但要求对象所属的类必须实现了Measurable接口。25面向对象高级程序设计面向对象高级程序设计接口接口public class DataSet .public void add(Measurable x)sum=sum+x.getMeasure();if(count=0|maximum.getMeasure()x.getMeasure()maximum=x;count+;public Measurable getMaximum()return maximum;private double sum;private Measurable maximum;private int count;26面向对象高级程序设计面向对象高级程序设计接口接口v接口接口VS 类类接口中所有的方法都是抽象的,即有方法名,接口中所有的方法都是抽象的,即有方法名,方法参数,返回值,但没有方法体;方法参数,返回值,但没有方法体;接口中的方法的访问限制权限都是接口中的方法的访问限制权限都是public;接口中没有成员变量,但可以有常量;接口中没有成员变量,但可以有常量;27面向对象高级程序设计面向对象高级程序设计接口接口v实现接口实现接口用关键词用关键词implements来标识一个类实现了某个接口;来标识一个类实现了某个接口;public class BankAccount implements Measurable public double getMeasure()return balance;/Additional methods and fields 类可以实现多个接口类可以实现多个接口;-类必须完成其实现的所有接口中的所有方法;类必须完成其实现的所有接口中的所有方法;28面向对象高级程序设计面向对象高级程序设计接口接口v接口使得类和类之间的藕合度减少;接口使得类和类之间的藕合度减少;Eg:DataSet、BankAccount和和Student的的UML图图 -矩形框表示一个类,矩形框中如果有矩形框表示一个类,矩形框中如果有interface表示一个接口;表示一个接口;-虚线加上一个空的三角形箭头表示虚线加上一个空的三角形箭头表示”is-a”关系;关系;-虚线加上一个箭头表示虚线加上一个箭头表示”uses”关系;关系;29面向对象高级程序设计面向对象高级程序设计接口接口使用接口前的使用接口前的UML图图30面向对象高级程序设计面向对象高级程序设计接口接口使用接口后的使用接口后的UML图图31面向对象高级程序设计面向对象高级程序设计接口接口v接口定义语法接口定义语法publicinterfaceInterfaceName/method signaturesExample:publicinterfaceMeasurabledoublegetMeasure();注:接口中的方法体自动为注:接口中的方法体自动为public32面向对象高级程序设计面向对象高级程序设计接口接口v类实现接口语法类实现接口语法publicclassClassNameimplementsInterfaceName,InterfaceName,./methods/instancevariablesExample:publicclassBankAccountimplementsMeasurable/OtherBankAccountmethodspublicdoublegetMeasure()/Methodimplementation33面向对象高级程序设计面向对象高级程序设计接口接口v如果想用如果想用DataSet类返回一组类返回一组Country对象中人对象中人口最多的一个对象,口最多的一个对象,Country类应该满足什么条类应该满足什么条件?件?v可否将可否将DataSet类的类的 public void add(Measurable x)方法的参方法的参数类型改为数类型改为Object?34面向对象高级程序设计面向对象高级程序设计接口接口v接口和类的互换接口和类的互换 DataSetbankData=newDataSet();bankData.add(newBankAccount(1100);publicvoidadd(Measurablex)如果一个类实现了某个接口,则将该类转换为该如果一个类实现了某个接口,则将该类转换为该接口是正确的,而且不需要强制转换;接口是正确的,而且不需要强制转换;35面向对象高级程序设计面向对象高级程序设计接口接口v接口和类的互换接口和类的互换 DataSetbankData=newDataSet();bankData.add(newBankAccount(1100);bankData.add(newBankAccount(2100);bankData.add(newBankAccount(2100);Measurablem=bankData.getMaxium();m.deposit(3000);/上面的语句是非法的36面向对象高级程序设计面向对象高级程序设计接口接口v接口和类的互换接口和类的互换接口转换为某个实现了该接口的类,需要用强接口转换为某个实现了该接口的类,需要用强制转换制转换 BankAccountm=(BankAccout)bankData.getMaxium();m.deposit(3000);37面向对象高级程序设计面向对象高级程序设计接口接口v接口与多态接口与多态接口不能实例化接口不能实例化Measurablem=new Measuable();/wrong!一个对象只能是实现了该接口的某个类的实例一个对象只能是实现了该接口的某个类的实例Measurable x;x=new BankAccount(10000);x=new Studnet(“Jack);调用对象的方法调用对象的方法 x.getMeasure();?调用了哪个方法调用了哪个方法38面向对象高级程序设计面向对象高级程序设计接口接口v接口与多态接口与多态接口可实现运行时的多态,在运行阶段,由对接口可实现运行时的多态,在运行阶段,由对象的实际类型决定调用哪一个具体的方法象的实际类型决定调用哪一个具体的方法 -如果如果x是一个是一个BankAccount对象,则调用对象,则调用BankAccount.getMeasure();-如果如果x是一个是一个Student对象,则调用对象,则调用Student.getMeasure();39面向对象高级程序设计面向对象高级程序设计接口接口v接口与回调接口与回调(callback)vMeasurable接口的限制接口的限制 -只能对用户自己编写的类实现该接口只能对用户自己编写的类实现该接口,不适用系统自带的不适用系统自带的类类 -测量形式比较简单。测量形式比较简单。v回调:一种常见的程序设计模式。可以指出某个特定事件回调:一种常见的程序设计模式。可以指出某个特定事件发生时应该采取的动作。发生时应该采取的动作。v改写改写Measurable -在前面的在前面的DataSet实现中,测量的实现依赖于调用该方实现中,测量的实现依赖于调用该方法的对象;法的对象;-改进:将需要测量的对象传递给一个测量方法:改进:将需要测量的对象传递给一个测量方法:public interface Measurer double measure(Object anObject);40vclassDataSetprivatedoublesum;privateObjectmaximum;privateintcount;privateMeasurermeasurer;/添加测量器对象41面向对象高级程序设计面向对象高级程序设计接口接口v修改后的修改后的add()方法方法publicvoidadd(Objectx)sum=sum+measurer.measure(x);if(count=0|measurer.measure(maximum)measurer.measure(x)maximum=x;count+;42面向对象高级程序设计面向对象高级程序设计接口接口v可以定义一个测量器对相关类的对象进行任何形式的测量可以定义一个测量器对相关类的对象进行任何形式的测量publicclassRectangleMeasurerimplementsMeasurerpublicdoublemeasure(ObjectanObject)RectangleaRectangle=(Rectangle)anObject;doublearea=aRectangle.getWidth()*aRectangle.getHeight();returnarea;(rectangle是系统自带的类,表示一个矩形)43面向对象高级程序设计面向对象高级程序设计接口接口v将测量器传给一个将测量器传给一个DataSet对象对象 Measurer m=new RectangleMeasurer();DataSet data=new DataSet(m);data.add(new Rectangle(5,10,20,30);data.add(new Rectangle(10,20,30,40);System.out.println(“Average area=”+data.getAverage();Rectangle max=(Rectangle)data.gatMaximum();System.out.println(“Maximum area rectangle=”+max);44面向对象高级程序设计面向对象高级程序设计接口接口(在面向(在面向对象象设计时,需要降低,需要降低类与与类之之间的耦合性)的耦合性)45面向对象高级程序设计面向对象高级程序设计接口接口v示例程序示例程序1DataSetTest46面向对象高级程序设计面向对象高级程序设计内部类内部类v对于一些用途很有限的类,可将其放在要使用的方法内;对于一些用途很有限的类,可将其放在要使用的方法内;publicclassDataSetTesterpublicstaticvoidmain(Stringargs)classRectangleMeasurerimplementsMeasurer.Measurerm=newRectangleMeasurer();DataSetdata=newDataSet(m);.定义在方法体内的内部类定义在方法体内的内部类,仅对该方法可见仅对该方法可见,方法体外不可方法体外不可访问访问.47面向对象高级程序设计面向对象高级程序设计内部类内部类v任何定义在其它类内部的类,都是内部类;v内部类除了可定义在其它类的方法体内,还可以定义在方法体外;v编译器会将内部类编译为一个普通类;DataSetTester$1RectangleMeasure.class48面向对象高级程序设计面向对象高级程序设计内部类内部类v定义语法DeclaredinsideamethodclassOuterClassNamemethod signature/方法签名.classInnerClassName/methods/fields.49面向对象高级程序设计面向对象高级程序设计内部类内部类v定义语法DeclaredinsidetheclassclassOuterClassName/methods /fieldsaccessSpecifierclassInnerClassName/methods /fields.50面向对象高级程序设计面向对象高级程序设计内部类内部类v示例DataSetTest351面向对象高级程序设计面向对象高级程序设计作业作业v完善自己编写的类完善自己编写的类1.编写equals()和toString()方法;2.实现接口Measurable()(任选课堂上的一种实现方式)以下为各类的测量标准:学生:年龄;老师:年龄;教室:面积;课程:学分;电脑:价格;仿照示例程序1,完成自己的程序;52