实验目的:
- 掌握编写不同包的子类时设置成员访问权限;
- 掌握Object类与其他类的关系以及toString()、equals(Object o)方法的作用;
- 掌握方法覆盖时必须保证方法原型的一致性;
- 掌握类型上转型(上溯)和下转型(下溯)的应用;
●参考学时:2学时
●基本要求:
- 在“实验4”包中编写“实验2.Point”和“实验2.Circle”类的子类“实验4.Point”、“实验4.Circle”,并编写新的构造方法,重写equals()方法和toString()方法;
- 在“实验4”包中编写测试类实验4.Test,并测试上述方法的正确性。
●实验提示:
- equals方法的参数类型必须是Object,访问修饰符必须是public,返回类型必须是boolean,否则该方法不是对从父类继承的public boolean equals(Object obj)方法的覆盖,至多算是该方法的重载。
- Circle类的equals方法不能写成如下代码:
public boolean equals(Object obj) {
if(obj instanceof Circle){
Circle c=(Circle)obj;
return c.getRadius()==getRadius() &&
c.getCenter().equals(getCenter());
}
return false;
}
以上代码试图通过c.getCenter().equals(getCenter())语句调用实验4.Point类的equals方法,从而判断圆心是否为同一点。这种写法的错误之处在于实验4.Circle的center变量是实验2.Point类的对象,而实验2.Point类的equals方法并没有判断XY坐标值是否相同。
表4.1 测试案例(仅用于编码测试)
编号 | 测试目的 | 输入或测试数据 | 期望结果 |
1 | 成员的private、public修饰 | 构造方法中直接访问Point类的x、y或Circle类的center、radius | 提示语法错误 |
2 | 子类的构造方法 | 创建实验4.Point()对象p1和实验4.Point(0,10)对象p2 | p1.getX()结果为0,p1.getY()结果为0,p1.distance(p2)结果为10 |
3 | 子类的构造方法 | 创建实验4.Circle()对象c1和实验4.Circle(0,0,10)对象c2 | c1.getCenter().getX()结果为0,c1.getCenter().getY()结果为0,c1.area()为0,c1.perimeter()结果为0,调用c1.relation(c2)结果为“同心圆” |
4 | toString()方法 | 调用p1.toString() | 返回“(0,0)” |
5 | toString()方法 | 调用c1.toString() | 返回“(0,0),0” |
6 | equals()方法 | 创建实验4.Point()对象p1和实验4.Point(0,10)对象p2 | 调用p1.equals(p2)时返回false |
7 | equals()方法 | 创建实验4.Point()对象p1和实验4.Point(0, 0)对象p2 | 调用p1.equals(p2)时返回true |
8 | equals()方法 | 创建实验4.Point()对象p1和实验2.Point(0, 0)对象p2 | 调用p1.equals(p2)时返回true |
9 | equals()方法 | 创建实验4.Point()对象p1和实验2.Point(0, 0)对象p2 | 调用p2.equals(p1)时返回false(因为实验2.Point还没有重写equals方法) |
10 | equals()方法 | 创建实验4.Circle()对象c1和实验4.Circle(0,0,10)对象c2 | 调用c1.equals(c2)时返回false |
11 | equals()方法 | 创建实验4.Circle()对象c1和实验4.Circle(0,0,0)对象c2 | 调用c1.equals(c2)时返回true |
12 | equals()方法 | 创建实验4.Circle()对象c1、实验4.Point(0,0)对象p和实验4.Circle(p,0)对象c2 | 调用c1.equals(c2)时返回true 调用c1.equals(p)和p.equals(c1)皆返回false |
13 | equals()方法 | 创建实验4.Circle()对象c1、实验2.Point(0,0)对象p和实验4.Circle(p,0)对象c2 | 调用c1.equals(c2)时返回true |
14 | equals()方法 | 创建实验4.Circle()对象c1和实验2.Circle(0,0,0)对象c2 | 调用c1.equals(c2)时返回true,调用c2.equals(c1)时返回false |
代码部分
Circle类
package shiyan4;
import shiyan2.Point;
import static java.lang.Math.PI;
public class Circle extends shiyan2.Circle {
private Point center;
private int radius;
public Circle() {
center = new Point(0, 0);
radius = 0;
}
public Circle(int x, int y, int r) {
center = new Point(x, y);
radius = Math.max(r, 0);
}
public Circle(Point c, int r) {
if (c == null) {
center = new Point();
} else {
center = c;
}
radius = Math.max(r, 0);
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void setCenter(Point center) {
if (center == null) {
this.center = new Point();
} else {
this.center = center;
}
}
public Point getCenter() {
return center;
}
public double perimeter() { //返回圆的周长
return 2 * PI * this.radius;
}
public double area() {
return PI * this.radius * this.radius;
}
public int relation(shiyan4.Circle c) {
if ((this.center.getX() == c.center.getX()) && (this.center.getY() == c.center.getY()) && (radius == c.radius)) {
return 0;
} else if ((this.center.getX() == c.center.getX()) && (this.center.getY() == c.center.getY())) {
return 1;
} else if ((c.center.distance(this.center) < this.radius + c.radius) && (c.center.distance(this.center) > Math.abs(this.radius - c.radius))) {
return 2;
} else if ((this.center != c.center) && (c.center.distance(this.center) >= (this.radius + c.radius))) {
return 3;
} else if ((this.center != c.center) && (c.center.distance(this.center)) <= Math.abs(this.radius - c.radius)) {
return 4;
}
return -1;
}
@Override
public boolean equals(Object obj) {
boolean flag = false;
if (obj instanceof shiyan2.Circle c) {
if (c.getCenter().getX() == this.center.getX() && c.getCenter().getY() == this.center.getY() && c.getRadius() == this.radius) {
flag = true;
}
}
return flag;
}
@Override
public String toString() {
return "圆心坐标:" + "(" + center.getX() + "," + center.getY() + ")" + " " + "半径" + radius;
}
}
Point类
package shiyan4;
public class Point extends shiyan2.Point {
private int x;
private int y;
public Point() {
x = 0;
y = 0;
}
public Point(shiyan2.Point a) {
if (a == null) {
this.x = 0;
this.y = 0;
return;
}
this.x = a.getX();
this.y = a.getY();
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public double distance(shiyan4.Point P) {
return Math.sqrt((this.x - P.x) * (x - P.x) + (this.y - P.y) * (y - P.y));
}
@Override
public boolean equals(Object obj) {
boolean flag = false;
if (obj instanceof shiyan2.Point p) {
if (p.getX() == this.getX() && p.getY() == this.getY()) {
flag = true;
}
}
return flag;
}
@Override
public String toString() {
return "圆心坐标:" + "(" + getX() + "," + getY() + ")";
}
}
Test类
package shiyan4;
public class Test {
public static void main(String[] args) {
System.out.println("--------------分割线1-------------------");
Point p = new Point();
Circle c = new Circle();
//p.x;p.y;c.center;c.radius;
System.out.println("--------------分割线2-------------------");
shiyan4.Point p1 = new shiyan4.Point();
shiyan4.Point p2 = new shiyan4.Point(0, 10);
System.out.println(p1.getX());
System.out.println(p1.getY());
System.out.println(p1.distance(p2));
System.out.println("--------------分割线3-------------------");
shiyan4.Circle c1 = new shiyan4.Circle();
shiyan4.Circle c2 = new shiyan4.Circle(0, 0, 10);
System.out.println(c1.getCenter().getX());
System.out.println(c1.getCenter().getY());
System.out.println(c1.area());
System.out.println(c1.perimeter());
int a = c1.relation(c2);
if (a == 0) {
System.out.println("同一个圆");
} else if (a == 1) {
System.out.println("同心圆");
} else if (a == 2) {
System.out.println("相交的圆");
} else if (a == 3) {
System.out.println("分离的圆");
} else if (a == 4) {
System.out.println("包含的圆");
}
System.out.println("--------------分割线4-------------------");
System.out.println(p1.toString());
System.out.println("--------------分割线5-------------------");
System.out.println(c1.toString());
System.out.println("--------------分割线6-------------------");
shiyan4.Point p3 = new shiyan4.Point();
shiyan4.Point p4 = new Point(0, 10);
System.out.println(p3.equals(p4));
System.out.println("--------------分割线7-------------------");
shiyan4.Point p5 = new shiyan4.Point();
shiyan4.Point p6 = new shiyan4.Point(0, 0);
System.out.println(p5.equals(p6));
System.out.println("--------------分割线8-------------------");
shiyan4.Point p7 = new shiyan4.Point();
shiyan2.Point p8 = new shiyan2.Point();
System.out.println(p7.equals(p8));
System.out.println("--------------分割线9-------------------");
shiyan4.Point p9 = new shiyan4.Point();
shiyan2.Point p10 = new shiyan2.Point(0, 0);
System.out.println(p10.equals(p9));
System.out.println("--------------分割线10-------------------");
shiyan4.Circle c3 = new shiyan4.Circle();
shiyan4.Circle c4 = new shiyan4.Circle(0, 0, 10);
System.out.println(c3.equals(c4));
System.out.println("--------------分割线11-------------------");
shiyan4.Circle c5 = new shiyan4.Circle();
shiyan4.Circle c6 = new Circle(0, 0, 0);
System.out.println(c5.equals(c6));
System.out.println("--------------分割线12-------------------");
shiyan4.Circle c7 = new shiyan4.Circle();
shiyan4.Point p11 = new shiyan4.Point(0, 0);
shiyan4.Circle c8 = new shiyan4.Circle(p11, 0);
System.out.println(c7.equals(c8));
System.out.println(c7.equals(p11));
System.out.println(p11.equals(c7));
System.out.println("--------------分割线13-------------------");
shiyan4.Circle c9 = new shiyan4.Circle();
shiyan2.Point p12 = new shiyan2.Point(0, 0);
shiyan4.Circle c10 = new shiyan4.Circle(p12, 0);
System.out.println(c9.equals(c10));
System.out.println("--------------分割线14-------------------");
shiyan4.Circle c11 = new shiyan4.Circle();
shiyan2.Circle c12 = new shiyan2.Circle(0, 0, 0);
System.out.println(c11.equals(c12));
System.out.println(c12.equals(c11));
}
}