面向对象的高级程序设计(1).ppt
面向对象的高级程序设计,伍淳华北京邮电大学计算机学院,Java,面向对象高级程序设计,继承object类,所有类都是Object的子类;Object obj=new BackAccount();Object obj=new String(“Hello”);,Java,面向对象高级程序设计,继承object类,equals方法toString方法clone方法在自己编写的类中,最好重写这些方法!,Java,面向对象高级程序设计,继承object类,equals方法public boolean equals(Object obj)return(this=obj);判断两个对象是否具有相同的引用,Java,面向对象高级程序设计,继承object类,equals方法 class BankAccount public boolean equals(Object obj)BankAccount other=(BankAccount)obj;return(accountNumber=other.accountNumber&balance=other.balance),Java,面向对象高级程序设计,继承object类,equals方法 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),Java,面向对象高级程序设计,继承object类,子类中实现equals方法 首先调用超类的equals,如果未通过测试,对象就不可能相等;如果超类中的域都相等,就比较子类中的实例域;,Java,面向对象高级程序设计,继承object类,子类中实现equals方法class SavingAccount extends BankAccount public boolean equals(Object obj)if(!super.equals(obj)return false;SavingAccount other=obj;return/比较SavingAccount中的成员变量,Java,面向对象高级程序设计,继承object类,Java语言规范要求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;,Java,面向对象高级程序设计,继承object类,注意: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),Java,面向对象高级程序设计,继承object类,注意: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),Java,面向对象高级程序设计,继承object类,注意:如果子类能够拥有自己的相等概念,那么对称性需求将强制采用getClass进行检测;如果由超类决定相等的概念,则可以使用instanceof进行检测,这样可以在不同子类的对象之间进行相等的比较.,Java,面向对象高级程序设计,继承object类,hashCode方法hasCode方法返回一个整型数值,并合理地组合实例域的散列码,以便能够让各个不同的对象产生的散列码更加均匀;如果x.equals(y)返回true,那么x.hashCode()就必须与y.hashCode()具有相同的值;如果重新定义equals方法,就必须重新定义hashCde方法;Object类的hashCode()方法返回对象的存储地址;,Java,面向对象高级程序设计,继承object类,hashCode方法class BankAccountpublic int hashCode()return 7*Integer(accountNumber).hashCode()+11*Double(balance).hashCode();,Java,面向对象高级程序设计,继承object类,toString方法 返回对象的字符串表示;Object类中默认返回对象所属的类名和散列码.System.out.println(System.out);输出:java.io.PrintStreama90653,Java,面向对象高级程序设计,继承object类,toString方法 重写toString方法一般遵循的格式为:类名成员变量值 java.awt.Pointx=20,y=20BankAccout中的toString函数可改写为:public String toString()retrun“BankAccoutbalance=“+balance+”,accountNumber=“+accountNumber+”;,Java,面向对象高级程序设计,继承object类,toString方法public String toString()retrun getClass().getName()+”balance=“+balance+”,accountNumber=“+accountNumber+”;,Java,面向对象高级程序设计,继承object类,toString方法class SavingAccount extends BankAccountpublic String toString()retrun super.toString()+”interest=“+interest+”;,Java,面向对象高级程序设计,接口,接口代码重用Eg:DataSet,Java,面向对象高级程序设计,接口,接口代码重用 如果想计算一组BankAccount对象中余额的最大值和平均值?,Java,面向对象高级程序设计,接口,接口代码重用 public class DataSet.public void add(BankAccount x)sum=sum+x.getBalance();if(count=0|maximum.getBalance()x.getBalance()maximum=x;count+;public BankAccount getMaximum()return maximum;private double sum;private BankAccount maximum;private int count;,Java,面向对象高级程序设计,接口,接口代码重用 public class DataSet.public void add(Student x)sum=sum+x.getScore();if(count=0|maximum.getScore()x.getBalance()maximum=x;count+;public Student getMaximum()return maximum;private double sum;private Student maximum;private int count;,Java,面向对象高级程序设计,接口,接口代码重用X的数据类型;如果每个对象实现一个getMeasure方法来提供测量的内容,就可实现一个可重用的DataSet,以add()方法为例:sum=sum+x.getMeasure();if(count=0|maximum.getMeasure()x.getMeasure()maximum=x;count+;X的数据类型应该是什么?-X的数据类型可以是任意实现了getMeasure()的类。,Java,面向对象高级程序设计,接口,接口可用来规范类的行为,只包含常量和方法的定义,而没有变量和方法的实现。接口的定义接口的定义包括接口声明和接口体完整的接口声明:public interface interfaceNameextends listOfSuperInterface 接口体包括常量定义和方法定义-常量定义格式为:type NAME=value;该常量被实现该接口的多个类共享;缺省的具有public,final,static的属性。-方法体定义格式为:(缺省的具有 public和abstract属性)returnType methodName(paramlist);,Java,面向对象高级程序设计,接口,接口的定义Example:public interface Measurable double getMeasure();,Java,面向对象高级程序设计,接口,接口的实现在类的声明中用implements子句来表示一个类实现某个接口一个类可以实现多个接口,在implements子句中用逗号分开在类体中可以使用接口中定义的常量,必须实现接口中定义的所有方法。,Java,面向对象高级程序设计,接口,接口的实现例:public class BankAccount implements Measurable/Other BankAccount methods public double getMeasure()/Method implementation,Java,面向对象高级程序设计,接口,接口类型的使用接口作为一种引用类型来使用可以声明接口的一个变量,但不能实例化 Measurable m=new Measurable();/wrong接口可以指向任何实现该接口的类的实例;Measurable m=new BankAccount();通过这些接口变量可以访问类所实现的接口中的方法。,Java,面向对象高级程序设计,接口,接口代码重用public interface Measurabledouble getMeasure();,Java,面向对象高级程序设计,接口,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;,Java,面向对象高级程序设计,接口,DataSet可以返回一组对象中值最大的那个对象,并计算出这一组对象的平均值,但要求对象所属的类必须实现了Measurable接口。,Java,面向对象高级程序设计,接口,public class DataSetTester public static void main(String args)DataSet bankData=new DataSet();bankData.add(new BankAccount(0);bankData.add(new BankAccount(10000);bankData.add(new BankAccount(2000);System.out.println(Average balance=+bankData.getAverage();Measurable max=bankData.getMaximum();System.out.println(Highest balance=+max.getMeasure();,Java,面向对象高级程序设计,接口,接口VS 类接口中所有的方法都是抽象的,即有方法名,方法参数,返回值,但没有方法体;接口中的方法的访问限制权限都是public;接口中没有成员变量,但可以有常量;,Java,面向对象高级程序设计,接口,接口使得类和类之间的藕合度减少;Eg:DataSet、BankAccount和Student的UML图-矩形框表示一个类,矩形框中如果有interface表示一个接口;-虚线加上一个空的三角形箭头表示”is-a”关系;-虚线加上一个箭头表示”uses”关系;,Java,面向对象高级程序设计,接口,使用接口前的UML图,Java,面向对象高级程序设计,接口,使用接口后的UML图,Java,面向对象高级程序设计,接口,如果想用DataSet类返回一组Country对象中人口最多的一个对象,Country类应该满足什么条件?可否将DataSet类的 public void add(Measurable x)方法的参数类型改为Object?,Java,面向对象高级程序设计,接口,接口和类的互换 DataSet bankData=new DataSet();bankData.add(new BankAccount(1100);public void add(Measurable x)如果一个类实现了某个接口,则将该类转换为该接口是正确的,而且不需要强制转换;,Java,面向对象高级程序设计,接口,接口和类的互换 DataSet bankData=new DataSet();bankData.add(new BankAccount(1100);bankData.add(new BankAccount(2100);bankData.add(new BankAccount(2100);Measurable m=bankData.getMaxium();m.deposit(3000);/上面的语句是非法的,Java,面向对象高级程序设计,接口,接口和类的互换接口转换为某个实现了该接口的类,需要用强制转换 BankAccount m=(BankAccout)bankData.getMaxium();m.deposit(3000);,Java,面向对象高级程序设计,接口,接口与多态接口不能实例化Measurable m=new Measuable();/wrong!一个对象只能是实现了该接口的某个类的实例Measurable x;x=new BankAccount(10000);x=new Studnet(“Jack);调用对象的方法 x.getMeasure();?调用了哪个方法,Java,面向对象高级程序设计,接口,接口与多态接口可实现运行时的多态,在运行阶段,由对象的实际类型决定调用哪一个具体的方法-如果x是一个BankAccount对象,则调用BankAccount.getMeasure();-如果x是一个Student对象,则调用Student.getMeasure();,Java,面向对象高级程序设计,接口,接口与回调(callback)Measurable接口的限制-只能对用户自己编写的类实现该接口。-测量形式比较简单。回调:一种常见的程序设计模式。可以指出某个特定事件发生时应该采取的动作。改写Measurable-在前面的DataSet实现中,测量的实现依赖于调用该方法的对象;-改进:将需要测量的对象传递给一个测量方法:public interface Measurer double measure(Object anObject);,Java,面向对象高级程序设计,接口,class DataSetprivate double sum;private Object maximum;private int count;private Measurer measurer;/添加测量器对象,Java,面向对象高级程序设计,接口,修改后的add()方法public void add(Object x)sum=sum+measurer.measure(x);if(count=0|measurer.measure(maximum)measurer.measure(x)maximum=x;count+;,Java,面向对象高级程序设计,接口,可以定义一个测量器对相关类的对象进行任何形式的测量public class RectangleMeasurer implements Measurable public double measure(Object anObject)Rectangle aRectangle=(Rectangle)anObject;double area=aRectangle.getWidth()*aRectangle.getHeight();return area;,Java,面向对象高级程序设计,接口,将测量器传给一个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.getMaximum();System.out.println(Maximum area rectangle=+max);.,Java,面向对象高级程序设计,接口,示例程序1 DataSetTest,Java,面向对象高级程序设计,接口,Java,面向对象高级程序设计,内部类,对于一些用途很有限的类,可将其放在要使用的方法内;public class DataSetTester public static void main(String args)class RectangleMeasurer implements Measurer.Measurer m=new RectangleMeasurer();DataSet data=new DataSet(m);.定义在方法体内的内部类,仅对该方法可见,方法体外不可访问.,Java,面向对象高级程序设计,内部类,任何定义在其它类内部的类,都是内部类;内部类除了可定义在其它类的方法体内,还可以定义在方法体外;编译器会将内部类编译为一个普通类;DataSetTester$1RectangleMeasure.class,Java,面向对象高级程序设计,内部类,定义语法Declared inside a method class OuterClassName method signature.class InnerClassName/methods/fields.,Java,面向对象高级程序设计,内部类,定义语法Declared inside the class class OuterClassName/methods/fields accessSpecifier class InnerClassName/methods/fields.,Java,面向对象高级程序设计,内部类,示例DataSetTest3,Java,面向对象高级程序设计,抽象方法与抽象类,子类继承父类时,子类可选择是否重写父类的方法;?是否可以强制要求子类重写某些方法 可以.采用抽象方法和抽象类来强制子类重写某些方法.,Java,面向对象高级程序设计,抽象方法与抽象类,抽象方法 抽象方法只需提供方法的声明,不用实现,即只有方法头,没有方法体,以关键字abstract标识;定义语法:public|private abstract returnType abstractMethodName(paramlist)示例:public abstract void introduction();,Java,面向对象高级程序设计,抽象方法与抽象类,抽象类 抽象类即是不能实例化的方法;以关键字abstract标识:定义语法:public|private abstract class abstractClassName 示例:public abstract class Person,Java,面向对象高级程序设计,抽象方法与抽象类,抽象类不一定要包含抽象方法;抽象类可以有自己的构造方法和成员变量;若类中包含了抽象方法,则该类必须被定义为抽象类;采用抽象类的一个原因是为了强制编程人员继承该类,同时实现该类中的抽象方法;?如果类Student继承自抽象类Person,但并没有完全实现Person中的抽象方法,则类Student是否是抽象类.?抽象类和接口的区别,Java,面向对象高级程序设计,抽象方法与抽象类,不能创建抽象类的对象可以定义抽象类的对象变量,但其只能引用非抽象子类的对象 示例:假设Person是抽象类,Student是其非抽象子类 Person p;p=new Person();/wrong p=new Studnent();/OK,Java,面向对象高级程序设计,作业,完善自己编写的类 1.编写equals()和toString()方法;2.实现接口Measurable()(任选课堂上的一种实现方式),使得可以应用DataSet类从一组你实现的对象中,求出平均值,及值最大的对象;以下为各类的测量标准:学生:年龄;老师:年龄;教室:面积;课程:学分;电脑:价格;可参照课堂上的示例程序完成;,Thank You!,MajpjMVcyzj21HLfrvy96dv02lPPfYgxUS7IYmZkyEmZ0kGeYZS3bpLCkYH1lt4EK7CxmUX3ijoYSOer7ZuaVWYgz4EpZrUirVpMzzvNtf1XZw5oswSXOtFaejnOcmfE1lZgnN1RSXg8wLCG8CVQ3XPJMvodPFWcpiYJgZazNSEPNIaklYSu7qSd1UpaxmZDlpN9zW7kljfsLCLi26Yv109ffbnDH8LbUN1G6ACURQ39eG12KHL9tXsZ1jzgoCK8g1kuNOh5eFvcmVT5ZYVQt9zk3rp3qLnf02FovEXxVRxjCcFRNppiJljNiOuk6fONnyX7fyGg7sXZ49BmCN5oy9VesHpKzdjTKwjrkCEQCFDehVmGax3lrOEbw63VscA3YSijtUKoCyiLzAlVRp7l4QgPNHxvJFFDyjUVN3oHlMah0XBd4uTbkfPIhHtw0evPmYOrdhEDoPwvYhzlGplU1AU9mpyiCXH8gpPCBRYjq77VcnbXumNE1yGfyTsbSj89J63kRTKDkKUg3mdS5sJ4X5cQ8dK7oW9IkScssECQdz2O9UTlpRjAFPChjhLdzopQzwxQf8ozdzOhogwAooXpUF83BX4C3jRgjDJiiXEUDMaNz4vQ4n164vspddHvOIVuBBdMA4xp1YhiHk0vOJ8TL1BxogzVlMpmod6ianYGmksQq6NWCEd56hZF4wfaNyZcrGfNxnPiG6ZAxSkfmhJAKtNmCqbRmppeXp8inz4eq3HkWCMSORyMMX522xpHG6basNr6KQfbZsFbHjzyNlJrruLolKFcC84dqfijBO5Dy2NaBcNEBPgQrT12PgpcKx2or2YChN5DPjs80zzdtdAdTKuW4uVv9bbZu3K2SZ2aEhTlIC1UqrIWibkzwHh6p8gLv26zr01mJybfOzFc4T7kQH1IpPwOzMDnAKPLsLrznXGjFNIA9bSWWms6ibKZwQIKrMzalwbFrQJvOP1rPH8rx2KkyYqrtQk5VRwM1HSX,