一、实验目的
- 理解面向对象编程,尤其是继承的思想,学习通过继承,在父类的基础上创建子类
- 使用关键字super调用父类的构造方法和方法
- 在子类中覆盖方法
二、实验内容
- (P380, 11.1)【三角形类Triangle】设计一个名为Triangle的类来扩展GeometricObject类。该类包括:
(1)三个名为side1、side2和side3的double数据域表示这个三角形的三条边,它们的默认值是1.0。
(2)一个无参构造方法创建默认的三角形。
(3)一个能创建带指定side1、side2和side3的三角形的构造方法。
(4)所有三个数据域的访问器方法。
(5)一个名为getArea()的方法返回这个三角形的面积。计算三角形面积的公式参见实验1练习题2.19。
(6)一个名为getPerimeter()的方法返回这个三角形的周长。
(7)一个名为toString()的方法返回这个三角形的字符串描述,显示三角形的三边长、周长及面积。
目标输出任务:
- 画出Triangle类和GeometricObject类的UML图。
- 实现这些类。
- 编写一个测试程序,创建边长为1、1.5和1,颜色为yellow,filled为true的Triangle对象,然后显示它的三边长、周长、面积、颜色以及是否被填充。
1.1 UML图
1.2 程序代码:
public class program1{
public static void main(String[] args){
Triangle triangle = new Triangle(1, 1.5, 1);
triangle.setColor("yellow");
triangle.setFilled(true);
System.out.println(triangle.toString());
}//main结束
}//program1结束
//创建Triangle类
public class Triangle extends GeometricObject{
double side1, side2, side3;
//创建无参构造方法
public Triangle(){
side1 = 1.0;
side2 = 1.0;
side3 = 1.0;
}
//创建有参构造方法
public Triangle(double side1, double side2, double side3){
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
double getSide1(){
return side1;
}
double getSide2(){
return side1;
}
double getSide3(){
return side1;
}
double getArea(){
//平均边长s
double s = ( side1 + side2 + side3 ) / 2.0;
//计算面积
return Math.sqrt( s * (s-side1) * (s-side2) * (s-side3) );
}//getArea结束
double getPerimeter(){
return side1+side2+side3;
}
public String toString(){
return "side1: " + side1 + "\tside2: " + side2 + "\tside3: " + side3 + "\nperimeter: " + getPerimeter() + "\tarea: " + getArea()
+ "\ncolor: " + getColor() + "\tfilled: " + isFilled();
}
}//Triangle类的创建结束
//创建GeometricObject类
class GeometricObject{
private String color = "white";
private boolean filled = false;
private java.util.Date dateCreated;
//无参构造函数
public GeometricObject(){
dateCreated = new java.util.Date();
}
public GeometricObject(String color, boolean filled){
dateCreated = new java.util.Date();
this.color = color;
this.filled = filled;
}
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
}
public boolean isFilled(){
return filled;
}
public void setFilled(boolean filled){
this.filled = filled;
}
public java.util.Date getDateCreated(){
return dateCreated;
}
public String toString(){
return "created on " + dateCreated + "\ncolor: " + color +" and filled: " + filled;
}
}//GeometricObject类结束
1.3 运行结果与分析:
运行结果正确,符合题目要求,输出三角形的三个边长、周长、面积、颜色及是否填充。
1.4 心得体会:
三角形类继承几何类,将三个类分别先画UML图再写成代码即可,中间细节问题需注意,如toString方法的重写。
- 【Circle2D类】定义Circle2D类,包括:
(1)两个带有get方法的名为x和y的double型数据域,表明圆的中心点。
(2)一个带get方法的数据域radius。
(3)一个无参构造方法,该方法创建一个(x,y)值为(0, 0)且radius为1的默认圆。
(4)一个构造方法,创建带指定的x、y和radius的圆。
(5)一个返回圆面积的方法getArea()。
(6)一个返回圆周长的方法getPerimeter()。
(7)如果给定的点(x, y)在圆内,那么方法contains(double x, double y)返回true。如图a所示。
(8)如果给定的圆在这个圆内,那么方法contains(Circle2D circle)返回true。如图b所示。
(9)如果给定的圆和这个圆重叠,那么方法overlaps(Circle2D circle)返回true。如图c所示。
目标输出任务:
- 画出该类的UML图。
- 实现这个类。
- 编写测试程序,创建一个Circle2D对象c1(new Circle2D(2, 2, 5.5)),显示它的面积和周长,还要显示c1.contains(3, 3)、c1.contains(new Circle2D(4, 5, 10.5))和c1.overlaps(new Circle2D(3, 5, 2.3))。
2.1 UML图
2.2 程序代码:
public class program2{
public static void main(String[] args){
Circle2D c1 = new Circle2D(2, 2, 5.5);
System.out.println("c1(2, 2, 5.5) area: " + c1.getArea()
+ "\tperimeter: " + c1.getPerimeter()
+ "\nc1.contains(3,3): " + c1.contains(3,3)
+ "\nc1.contains(new Circle2D(4, 5, 10.5)): "
+ c1.contains(new Circle2D(4, 5, 10.5))
+ "\nc1.overlaps(new Circle2D(3, 5, 2.3)): "
+ c1.overlaps(new Circle2D(3, 5, 2.3)) );
}//main函数结束
}//program2结束
//创建Circle2D类
class Circle2D{
double x, y, radius;
final double PI = 3.14;
//无参构造函数
Circle2D(){
x = 0;
y = 0;
radius = 1.0;
}
//有参构造函数
Circle2D(double x, double y, double radius){
this.x = x;
this.y = y;
this.radius = radius;
}
double getX(){
return x;
}
double getY(){
return y;
}
double getRadius(){
return radius;
}
//计算面积
double getArea(){
return PI * radius * radius;
}
//计算周长
double getPerimeter(){
return PI * radius * 2;
}
//判断给定点(x,y)是否在圆内
boolean contains(double x,double y){
//将该点代入圆的方程,若小于半径的平方则在圆内,反之则不在
return ( ((x-this.x)*(x-this.x) + (y-this.y)*(y-this.y)) < this.radius*this.radius ) ? true : false;
}
//判断给定的圆是否在圆内
boolean contains(Circle2D circle){
//比较给定圆的半径与已定的半径,若给定圆的半径大则
//定不在已定圆内,反之继续判断
if(this.radius > circle.getRadius()){
//半径差
double m = this.radius - circle.getRadius();
//圆心距
double n = Math.sqrt((circle.getX()-this.x)*(circle.getX()-this.x)
+(circle.getY()-this.y)*(circle.getY()-this.y));
//圆心距如果在0-半径差之间,则给定圆在已定圆内,反之不在
return (n>=0 && n<m) ? true : false;
}
else
return false;
}
//判断两个圆是否重叠
boolean overlaps(Circle2D circle){
//圆心距
double n = Math.sqrt((circle.getX()-this.x)*(circle.getX()-this.x)
+(circle.getY()-this.y)*(circle.getY()-this.y));
//半径差
double m = (this.radius > circle.getRadius()) ? this.radius-circle.getRadius() : circle.getRadius()-this.radius;
//如果圆心距在半径差与半径和之间,则重叠,反之不重叠
return (n>m && n<(this.radius+circle.getRadius())) ? true : false;
}
}//Circle2D类结束
2.3 运行结果与分析:
运行正确,符合题目要求,输出圆的面积和周长,判断点(3,3)是否在圆内,是否蕴含圆心(4,5)半径10.5的圆,与圆心(3,5)半径2.3的圆是否重叠。
2.4 心得体会:
这是一个位置类,注意判断条件即可。