实验4 抽象类和接口
【实验宗旨】
每天做一点编程练习。
【实验目的】
1、学习和掌握Java抽象类的定义和使用。
2、学习和掌握Java接口的定义和使用。
3、进一步学习和掌握通用程序设计方法。
【实验步骤(解题过程)】
参见实验2。
【实验内容】
1、(CompareableCirlce类)创建名为CompareableCircle类,它扩展Circle类并实现Compareable接口。画出UML图,实现compareTo方法,使其可以根据面积比较两个圆。编写一个测试程序求出CompareableCircle对象的两个实例中的较大者。
说明:⑴来源编程练习14.2(P399))。⑵https://www.wendangku.net/doc/ed9906262.html,pareable接口参见14.5小节(P378)。⑶Circle类的实现,参见程序清单11.2(P303)。
【实验预习】
1.问题描述:该题描述的是创建一个CompareableCircle类来实现两个圆的比
较。
2.创建两个CompareableCircle类的实例,利用Comparable接口,并调用
ComparableMax方法实现。
【附程序代码】
@SuppressWarnings("unchecked")
public class testCompareableCircle{
//主方法
public static void main(String[]args){
CompareableCircle C1=new CompareableCircle(10);
CompareableCircle C2=new CompareableCircle(3);
System.out.println("The maxnium Circle is "+ComparableMax(C1,C2)+"的圆");
}
//比较两个圆的大小
public static Comparable ComparableMax(Comparable C1,Comparable C2)
{
if(https://www.wendangku.net/doc/ed9906262.html,pareTo(C2)>0)
return C1;
else return C2;
}
}
public class CompareableCircle extends Circle implements Comparable{ //建立个指定半径的圆
CompareableCircle(double radius){
super(radius);
}
//Comparable接口的方法
public int compareTo(Object o){
if(getArea()>((CompareableCircle)o).getArea())
return 1;
else if(getArea()<((CompareableCircle)o).getArea()) return -1;
else return 0;
}
}
public class Circle extends GeometricObject1 {
private double radius;
public Circle() {
}
public Circle(double radius) {
this.radius = radius;
}
//返回半径
public double getRadius() {
return radius;
}
//设置一个新的半径
public void setRadius(double radius) {
this.radius = radius;
}
//返回圆的面积
public double getArea() {
return radius * radius * Math.PI;
}
//返回圆的直径
public double getDiameter() {
return 2 * radius;
}
//返回圆的周长
public double getPerimeter() {
return 2 * radius * Math.PI;
}
//打印圆的信息
public String toString() {
return "created in" + getDateCreated() +
" and the radius is " + radius;
}
}
【Uml图】
【实验过程及运行结果】
在运行过程中遇到的错误是,在写ComparableMax方法时,我写的返回值是ComparableCircle类型。
应该返回值的类型是Comparable类型。这样直接调用了它的ToString方法。
2、(将Circle类变成可比较的)改写程序清单11-2(P303)中的Circle类,它扩展G eometricObject类(程序清单14-1(P371)),
并实现Compareable接口。覆盖Object类中的equals方法。当两个Circle对象所表示的圆的半径相等时,则这两个对象是相同的。画出包括Circle、GeometricObject和Compareble的UML图。编写测试程序,判断两个圆是否相同。如果不同,按照练习1的思路,比较两个圆对象的大小。(来源:编程练习14.5(P399))。
【实验预习】
1.问题描述:创建Circle类,比较两个圆的大小。
2.创建两个Circle类的实例,调用CompareTo方法和equals方法,比较两个圆的
大小。
【附程序代码】
public class testCircle2{
public static void main(String[]args){
Circle1 C1=new Circle1(2);//建立一个半径为2的圆
Circle1 C2=new Circle1(3);//建立一个半径为3的圆
System.out.println(C1.equals(C2));
System.out.println(https://www.wendangku.net/doc/ed9906262.html,pareTo(C2);
}
}
public class Circle1 extends GeometricObject implements Comparable{ private double radius;
public Circle1() {
}
public Circle1(double radius) {
this.radius = radius;
}
//返回半径
public double getRadius() {
return radius;
}
//设置一个新的半径
public void setRadius(double radius) {
this.radius = radius;
}
//返回圆的面积
public double getArea() {
return radius * radius * Math.PI;
}
//返回圆的直径
public double getDiameter() {
return 2 * radius;
}
//返回圆的周长
public double getPerimeter() {
return 2 * radius * Math.PI;
}
//打印圆的信息
public String toString() {
return "created in" + getDateCreated() +
" and the radius is " + radius;
}
//Comparable接口的方法
public int compareTo(Object o) {
if (this.getArea() > ((Circle1)o).getArea())
return 1;
else if (this.getArea() < ((Circle1)o).getArea())
return -1;
else
return 0;
}
//覆盖Object中的equals方法
public boolean equals(Object o) {
return this.getArea() == ((Circle1)o).getArea();
}
}
【UML图】
【实验过程与运行结果】
在实验过程中,不会编写equals的覆盖方法。
解决方法:应该是写成; public boolean equals(Object o) {
return this.getArea() == ((Circle1)o).getArea();}
3、(求几何对象的面积之和)编写一个方法,求数组中所有几何对象的面积之和。方法签名如下:
public static double sumArea(GeometricObject[] a)
编写测试程序,创建4个对象(两个圆形和两个矩形)的数组,然后使用sumArea 方法求它们的总面积。
说明:⑴来源:编程练习14.8(P400);⑵分别实现Geometric Object类(程序清单14-1(P372))、Rectangle类(程序清单11-3(P305))和Circle类(程序清单11-2(P303));⑶建立GeometricObject类层次结构(图14-2(P372))。【附程序代码】
public class Area{
public static void main(String[] args) {
new Area();
}
public Area() {
GeometricObject[] a = {new Circle(5), new Circle(6),
new Rectangle(2, 3), new Rectangle(2, 3)};
System.out.println("The total area is " + sumArea(a));
}
public static double sumArea(GeometricObject[] a) {
double sum = 0;
for (int i = 0; i < a.length; i++)
sum += a[i].getArea();
return sum;
}
//矩形类
class Rectangle extends GeometricObject {
private double width;
private double height;
//创建一个指定长和宽的矩形
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
//返回矩形的宽
public double getWidth() {
return width;
}
//设定矩形的宽
public void setWidth(double width) {
this.width = width;
}
//返回举矩形的高
public double getHeight() {
return height;
}
//设定矩形的高
public void setHeight(double height) {
this.height = height;
}
//返回矩形面积
public double getArea() {
return width*height;
}
//求矩形的周长
public double getPerimeter() {
return 2*(width + height);
}
//覆盖equals方法
public boolean equals(Rectangle rectangle) { return (width == rectangle.getWidth()) && (height == rectangle.getHeight());
}
//返回基本信息
public String toString() {
return "[Rectangle] width = " + width +
" and height = " + height;
}
}
}
【运行结果】
【思考题】
1、练习1和练习2中,使用了不同的方法建立了可比较的Circle类。结合编程实现,说说你对不同设计方案的想法和体会。
利用不同的设计方案可易于解决不同的实际问题。
2、练习3中,如果将方法sumArea的参数数组定义为Cirlce[],可以实现相应的功能吗?定义为Object[]呢?为什么?结合本题,说说你对通用程序设计的理解。
前者不可以,后者可以。编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。
3、说说抽象类和接口的相同和不同之处。
. 相同点
都不能被直接实例化,都可以通过继承实现其抽象方法。
都是面向抽象编程的技术基础,实现了诸多的设计模式。
不同点
接口支持多继承;抽象类不能实现多继承。
接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。
接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。
接口可以用于支持回调;抽象类不能实现回调,因为继承不支持。
接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。
接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。