第一范文网 - 专业文章范例文档资料分享平台

《Java程序设计实用教程(第4版)习题解答与实验指导》第1~8章

来源:用户分享 时间:2025/6/6 16:49:10 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

public boolean equals(Student s) //子类增加,由子类提供对象比较规则

调用如下:

s1.equals(p1) s2.equals(s1)

//执行equals(Person),由父类提供对象比较规则 //执行equals(Student),由子类提供对象比较规则

由于重载是编译时多态,当父类对象引用子类实例时,运行时仍然执行父类提供的对象比较规则,而非子类对象比较规则。例如,以下运行时执行与希望不符:

Person p1 = new Student(……), p2 = new Student(……); //父类对象引用子类实例 p1.equals(p2)

//编译时多态,执行equals(Person),与希望不符

所以,Student类不需要重载以上两个equals()方法,而应声明equals(Person)覆盖父类方法,实现运行时多态。equals(Person)方法实现可约定子类对象与父类对象是否可比相等。

③ Student类声明equals(Person)方法,与父类实例可比

//子类覆盖父类方法,与父类实例可比,提供Person类型参数按Person规则比较

public boolean equals(Person p) //覆盖父类equals(Person)方法,约定子类对象比较规则 {

boolean b = super.equals(p); //调用父类equals(Person)方法,执行父类对象比较规则 if (b && p instanceof Student) //当父类成员变量对应相等且p引用子类实例时 { Student s = (Student)p; //类型强制转换,s也引用p引用的实例 return this.department.equals(s.department) && this.speciality.equals(s.speciality) && this.number.equals(s.number) && this.member==s.member; } return b; }

调用如下:

Person p1 = new Student(……), p2 = new Student(……); //父类对象引用子类实例 p1.equals(p2)

//运行时多态,执行子类对象比较规则

推而广之,每个类应该覆盖父类的equals()方法,参数是父类对象。Person类应该覆盖

Object类的equals(Object)方法,而Student类也该再覆盖父类的equals(Object)方法。所以,每个类应该覆盖equals(Object)方法,表现运行时多态性。

(3) Person和Student类声明equals(Object)方法,表现出运行时多态性。 ① Person类与本类及其子类对象可比相等,与之外的对象没有可比性。

Person类声明equals(Object)方法如下,它覆盖Object类的equals()方法,不支持与父类Object对象比较相等。

public boolean equals(Object obj) //覆盖Object类的equals()方法 {

if (this==obj) //this指代调用当前方法的对象 return true;

if (obj instanceof Person) //当obj引用实例属于Person及其子类 { Person p = (Person)obj; //类型强制转换,p也引用obj引用的实例 return this.name.equals(p.name) && this.birthday.equals(p.birthday) &&

this.sex.equals(p.sex) && this.province.equals(p.province) && this.city.equals(p.city);

- 31 -

}

return false; }

上述方法没有约定Person类与Person类及其子类以外对象的可比性,以下调用语法正确,但两个对象没有比较成员变量即返回false:

Person p1 = new Person(……), p2 = new Person(……); p1.equals(new Object()) p1.equals(p2)

//参数是Object实例,不比,返回false //参数是Person及其子类,可比

② Student类声明equals(Object)方法,与父类实例不可比。

Student类声明equals(Object)方法如下,没有提供与父类Person实例的比较规则。

public boolean equals(Object obj) //覆盖Person类中方法 {

if (this==obj) //this指代调用当前方法的对象 return true;

if (obj instanceof Student) //当obj引用实例属于Student及其子类 { Student s = (Student)obj; //类型强制转换,s也引用obj引用的实例 return this.department.equals(s.department) && this.speciality.equals(s.speciality) && this.number.equals(s.number) && this.member==s.member; }

return false; }

调用语句如下:

Person p1 = new Person(……), p2 = new Student(……), p3 = new Student(……);

p1.equals(p2) //编译时多态,执行Person的equals(Object),参数是Person的子类对象 p2.equals(p1) //运行时多态,false 执行Student的equals(Object),参数是Person类对象,不比,p2.equals(p3) //运行时多态,执行Student的equals(Object),参数是Student类对象,可比

③ Student类声明equals(Object)方法,与父类实例可比。

Student类声明equals(Object)方法,根据需要也可实现如下,与父类实例可比。

public boolean equals(Object obj) //覆盖父类方法,约定子类对象比较规则,与父类实例可比 {

boolean b = super.equals(p); //调用Person类equals(Object)方法,执行父类对象比较规则 if (b && p instanceof Student) //当父类成员变量对应相等且p引用子类实例时 { Student s = (Student)p;

//类型强制转换,s也引用p引用的实例

return this.department.equals(s.department) && this.speciality.equals(s.speciality) && this.number.equals(s.number) && this.member==s.member; } return b; }

调用语句如下:

Person p1 = new Person(\李小明\Person p2 = new Student(p1, ……);

- 32 -

p2.equals(p1) //子类对象与父类对象可比,true

【习3.6】 在对象数组中查找对象。

例3.6思考题,在对象数组中查找对象的search()方法声明如下:

//顺序查找对象数组中首次出现的与key相等元素,若查找成功返回元素,否则返回null public static Object search(Object value[], Object key) {

if (value!=null && key!=null) for(int i=0; i

if (key.equals(value[i])) //对象采用equals()方法比较是否相等,运行时多态 return value[i];

return null; //查找不成功 }

【问题】参数key已经引用一个实例,为什么还要找它?key引用的实例与最终找到的实例有什么不同?

【答】search()方法的查找结果取决于对象的equals(Object)方法比较相等结果。例如,前述Person和Student类的equals(Object)方法实现为比较所有成员变量的取值,则search()方法查找的结果对象与key参数引用实例取值相等,即没有必要执行search()方法。

但是,如果Person类声明equals()方法如下,只比较姓名作为对象相等依据,并且Student类继承它:

public boolean equals(Object obj) //只比较姓名作为对象相等依据

{ return this==obj || obj!=null && obj instanceof Person && this.name.equals(((Person)obj).name); }

则以下两个Person对象相等:

new Person(\张小莉\

new Student(\张小莉\电子信息\

因此,search(Object value[], Object key)方法用于在value对象数组中查找key,通常key只提供作为查找依据的关键字数据项,且由key的equals(Object)方法提供对象比较相等的规则。

3.5 类的抽象性

1. 抽象类

3-12 什么是抽象类?在什么情况下需要设计抽象类?抽象类中是否必须有抽象方法?

【答】使用关键字abstract声明的类称为抽象类,抽象类通常包含抽象方法,抽象方法是只有方法声明而没有方法体的成员方法,抽象类不能被实例化。

3-13 以下声明有什么错误?

public abstract class ClosedFigure { protected abstract ClosedFigure()

- 33 -

}

【答】编译错,构造方法不能被声明为抽象方法。 3-14 以下Shape类声明有什么错误?

public abstract class ClosedFigure { public ClosedFigure() { } public void print() { } public void finalize() { } }

【答】没有错误,抽象类也可以不包含抽象方法。 3-15 设ClosedFigure是抽象类,以下声明有什么错误?

ClosedFigure fig = new ClosedFigure();

【答】编译错,不能创建抽象类的实例。

3-16 如果ClosedFigure类中的area()方法声明如下,会对ClosedFigure的子类有何影响?

public class ClosedFigure {

public double area() { return 0; } }

【答】此处ClosedFigure类的area()方法没有意义。因为ClosedFigure的子类不是必须覆盖area()方法,如果没有覆盖,无论是什么对象,则图形面积总为0.0。

将area()方法声明为抽象方法,在编译时Java会自动检查子类是否覆盖了抽象方法。如果一个方法需要被子类覆盖,则必须声明为抽象方法。

2. 最终类

3-17 什么是最终类?在什么情况下需要设计最终类?最终类中是否必须有最终方法?

【答】使用关键字final声明的类称为最终类,最终类不能被继承。

实验3 类的封装、继承和多态

增加实验题如下。

3-18 声明复数类如下,复数语法图见教材图3.15所示。

public class Complex {

public double real,imag; //实部,虚部

public Complex(double real, double imag) //构造方法 public Complex(double real) //构造方法重载

- 34 -

《Java程序设计实用教程(第4版)习题解答与实验指导》第1~8章.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c319sl4reoy0zdc4257b2_9.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top