一、实验目的
1.设计和使用抽象类
2.定义接口以及实现接口的类
3.理解接口继承和多态
二、实验内容
1.(P455,13.1)【三角形类】设计一个扩展自抽象类GeometriObject的新的Triangle类。绘制Triangle类和GeometricObject类的UML图并实现Triangle类。编写一个测试程序,提示用户输入三角形的三条边、一种颜色以及一个表明该三角形是否填充的布尔值。程序应该根据用户的输入,使用这些边以及颜色和是否填充的信息,创建一个Triangle对象。程序应该显示面积、周长、颜色以及真或者假来表明是否被填充。
2.(P456, 13.6)【ComparableCircle类】创建名为ComparableCircle的类,它继承自Circle类,并实现Comparable接口。画出UML图并实现compareTo方法,使其根据面积比较两个圆。编写一个测试程序求出ComparableCircle对象的两个实例中的较大者。
3.(P456,13.7)【可着色接口Colorable】设计一个名为Colorable的接口,其中有名为howToColor()的void方法。可着色对象的每个类必须实现Colorable接口。设计一个扩展GeometricObject类并实现Colorable接口的名为Square的类。实现howToColor方法,显示消息“给所有的四条边着色”。
画出包含Colorable、Square和GeometricObject的UML图。编写一个测试程序,创建有五个GeometricObject对象的数组。对于数组中的每个对象而言,如果对象是可着色的,那就调用howToColor方法。
4.【附加题,可选做】【找出最大的对象】编写一个方法,返回对象数组中最大的对象。方法签名如下:
public static Object max(Comparable[] a)
所有对象都是Comparable接口的实例。对象在数组中的顺序是由compareTo方法决定的。
编写测试程序,创建一个由10个字符串构成的数组,一个由10个整数构成的数组和一个由10个日期构成的数组,找出数组中最大的字符串、整数和日期。
三、实验要求:
要求每个学生独立完成实验任务。
四、实验报告
1.实验结果与分析
(1)三角形类
A. UML类图
B. 实验运行
首先根据提示输入三个边的边长
然后接着根据提示输入字符串类型的颜色信息和布尔类型的填充信息
最后回车,输出信息
C.实验过程与结果分析
首先定义GeometricObject类并定义为抽象类,并定义抽象方法getArea方法和getPerimeter方法;
public abstract double getArea();
public abstract double getPerimeter();
然后定义Triangle类并继承自GeometricObject类,定义三个私有边长数据域。
private double s1,s2,s3;
定义构造方法。
this.s1 = s1;
this.s2 = s2;
this.s3 = s2;
setColor(color);
setFilled(filled);
Date dateCreated = new Date();
setDateCreated(dateCreated);
重写抽象getArea方法和getPerimeter方法。
public double getArea() {
double p = (s1+s2+s3) / 2;
return Math.sqrt(p*(p-s1)*(p-s2)*(p-s3));
}
public double getPerimeter(){
return s1 + s2 + s3;
}
重写已有toString方法。
public String toString(){
return super.toString() + " and area: " + getArea() + " and perimeter: " + getPerimeter();
}
然后在主方法内测试程序并调用构造方法构造三角形,然后返回测试信息。
created on Sun Jun 16 19:23:53 CST 2019
color: white and filled: false and area: 1054.8037435940394 and perimeter: 149.0
(2)ComparableCircle类
A. UML类图
B.实验运行
首先根据提示输入两个圆半径
回车返回哪个圆面积较大,并输出面积大小
C.实验过程与结果分析
首先定义ComparableCircle类,继承自Circle类,实现Comparable接口
public class ComparableCircle extends Circle implements Comparable<ComparableCircle>
然后重写Comparable内的抽象方法,根据大小关系返回大于0,等于0,小于0的值
public int compareTo(ComparableCircle d){
if(this.getArea() < d.getArea())return -1;
else if(this.getArea() == d.getArea())return 0;
else return 1;
}
再在主方法内测试程序,创建两个ComparableCircle类型的实例,输入两个半径值并用相关set方法定义实例,再根据调用的compareTo方法输出不同的值。
if(c1.compareTo(c2) < 0)System.out.println("两圆中的较大者为第二个,面积为" + c2.getArea());
else if(c1.compareTo(c2) == 0)System.out.println("两圆等大,面积为" + c2.getArea());
else System.out.println("两圆中的较大者为第一个,面积为" + c1.getArea());
两圆中的较大者为第二个,面积为201.06192982974676
(3)可着色接口Colorable
A. UML类图
B. 实验运行
直接回车运行产生结果
C. 实验过程与结果分析
首先创建Colorable接口并定义抽象方法howToColor
public interface Colorable {
public abstract void howToColor();
}
然后定义Square类,继承自GeometricObject类,实现Colorable接口
public class Square extends GeometricObject implements Colorable
再定义私有的是否可以涂颜色的布尔类型数据域和边长的double数据域和其set和get方法
private boolean canbecolored;
private double side;
重写GeometricObject类的抽象方法
@Override
public double getArea() {
return side * side;
}
@Override
public double getPerimeter() {
return 4 * side;
}
然后在主方法测试程序,设置一个GeometricObject类型,指向Square类型的一维数组,长度为5;然后循环对数组内的元素创建空间(注意在这里我们要将GeometricObject类型的对象强制转型到Square),然后随机设置是否可以涂色(使用Random类对象的nextBoolean方法)
GeometricObject[] geometricObjects = new Square[5];
for(int i = 0; i < 5;i++){
geometricObjects[i] = new Square();
((Square)geometricObjects[i]).setCanbecolored(random.nextBoolean());
}
再循环输出五个实例是否被涂色
for(int i = 0; i < 5;i++){
System.out.println("第" + (i+1) + "个对象");
if(((Square)geometricObjects[i]).getCanbecolor()){
((Square)geometricObjects[i]).howToColor();
}
else System.out.println("不可着色");
}
第1个对象
不可着色
第2个对象
给所有的四条边着色
第3个对象
不可着色
第4个对象
不可着色
第5个对象
给所有的四条边着色
(4)附加题:找出最大的对象
A.UML类图
B.实验运行
首先根据提示输入相关信息,其中日期以YYYY-MM-DD格式输入
回车,返回三种类型的最大值
C.实验过程与结果分析
首先根据题目要求定义max方法,其中Comparable是接口类,可以是这三类类型的实例数组,然后用instanceof语句判断是哪个类型。
if(a[0] instanceof String){return max;}
if(a[0] instanceof Date){return max;}
if(a[0] instanceof Integer){return max;}
return null;
在每个类型内循环遍历使用compareTo方法求最大值(以Date类为例)
Date max = (Date)a[0];
for(int i = 1;i < a.length;i++){
if(a[i].compareTo(max) > 0)max = (Date)a[i];
}
return max;
在主方法内定义三个类型的五个长度的数组
Integer[] num = new Integer[10];
String[] strings = new String[10];
Date[] dates = new Date[10];
然后输入内容,其中使用util库内的Date类,然后使用SimpleDateFormat类的时间类型定义(yyyy-mm-dd),然后用其内的方法parse(input.next())输入到Date类型实例中
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
for(int i = 0; i < 10;i++){
dates[i] = new Date();
dates[i] = simpleDateFormat.parse(input.next());
}
最后调用max方法,输出结果即可
int max1 = (int)max(num);
String max2 = (String)max(strings);
Date max3 = (Date)max(dates);
System.out.println("最大整数为: " + max1);
System.out.println("最大字符串为: " + max2);
System.out.println("最大日期为: " + max3);
3.心得体会
本次实验主要考查对抽象类与接口的方法的运用,同时在建立类与实例的连接上回顾了之前学过的继承与多态相关知识。
本次实验的难度比较适中,在学过的基础上其实更是针对性的强化,但在附加题的多态,接口和继承的综合应用时有难度的提升,首先遇到的就是Comparable接口是所有类型的父类的一个思想的运用就让我想了很长时间,还有Date类型参量传入的时候,刚开始想的是使用int类型传入,但是测试之后发现没办法转换,就将Date类从sql库转到了util库,再上网查到了SimpleDateFormat定义的方法,最后顺利解决这种问题。
本次是最后一次实验,在这八次实验中,我认为题目都是很有针对性且很有练习性的,这八次实验的应用,确实提高了我的有关Java的代码能力,同时对理论知识的掌握也在实践的过程中不断深化,实验课是十分有效果的。
4.附源代码
(1)experiment1
GeometricObject类
import java.util.Date;
public abstract class GeometricObject {
private String color = "white";
private boolean filled;
private Date dateCreated;
protected GeometricObject(){
dateCreated = new Date();
}
protected GeometricObject(String color,boolean filled){
dateCreated = new 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 void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getDateCreated() {
return dateCreated;
}
@Override
public String toString() {
return "created on " + dateCreated + " \ncolor: " + color
+ " and filled: " + filled;
}
public abstract double getArea();
public abstract double getPerimeter();
}
Triangle类
import java.util.Date;
import java.util.Scanner;
public class Triangle extends GeometricObject{
private double s1,s2,s3;
public Triangle(double s1,double s2,double s3,String color,boolean filled){
this.s1 = s1;
this.s2 = s2;
this.s3 = s2;
setColor(color);
setFilled(filled);
Date dateCreated = new Date();
setDateCreated(dateCreated);
}
public double getArea() {
double p = (s1+s2+s3) / 2;
return Math.sqrt(p*(p-s1)*(p-s2)*(p-s3));
}
public double getPerimeter(){
return s1 + s2 + s3;
}
public String toString(){
return super.toString() + " and area: " + getArea() + " and perimeter: " + getPerimeter();
}
public static void main(String[] args) {
double s1,s2,s3;
String color;
boolean filled;
Scanner input = new Scanner(System.in);
System.out.println("请输入三条边的值与颜色填充信息: ");
System.out.print("第一条边长");
s1 = input.nextDouble();
System.out.print("第二条边长");
s2 = input.nextDouble();
System.out.print("第三条边长");
s3 = input.nextDouble();
System.out.print("颜色信息");
color = input.next();
System.out.print("是否被填充");
filled = input.nextBoolean();
Triangle triangle = new Triangle(s1, s2, s3, color, filled);
System.out.println(triangle.toString());
}
}
(2)experiment2
Circle类
public class Circle {
private double radius = 1;
public Circle() {}
public Circle(double newRadius){
radius = newRadius;
}
public double getArea(){
return radius * radius * Math.PI;
}
public double getPerimeter(){
return 2 * radius * Math.PI;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
}
ComparableCircle类
import java.util.Scanner;
public class ComparableCircle extends Circle implements Comparable<ComparableCircle> {
public int compareTo(ComparableCircle d){
if(this.getArea() < d.getArea())return -1;
else if(this.getArea() == d.getArea())return 0;
else return 1;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ComparableCircle c1 = new ComparableCircle();
System.out.println("输入第一个圆的半径");
double r1 = input.nextDouble();
c1.setRadius(r1);
ComparableCircle c2 = new ComparableCircle();
System.out.println("输入第二个圆的半径");
double r2 = input.nextDouble();
c2.setRadius(r2);
if(c1.compareTo(c2) < 0)System.out.println("两圆中的较大者为第二个,面积为" + c2.getArea());
else if(c1.compareTo(c2) == 0)System.out.println("两圆等大,面积为" + c2.getArea());
else System.out.println("两圆中的较大者为第一个,面积为" + c1.getArea());
}
}
(3)experiment3
GeometricObject类:见experiment1
Colorable接口
public interface Colorable {
public abstract void howToColor();
}
Square类
import java.util.Random;
public class Square extends GeometricObject implements Colorable{
private boolean canbecolored;
private double side;
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
@Override
public void howToColor(){
System.out.println("给所有的四条边着色");
}
@Override
public double getArea() {
return side * side;
}
@Override
public double getPerimeter() {
return 4 * side;
}
public void setCanbecolored(boolean canbecolored) {
this.canbecolored = canbecolored;
}
public boolean getCanbecolor() {
return canbecolored;
}
public static void main(String[] args) {
Random random = new Random();
GeometricObject[] geometricObjects = new Square[5];
for(int i = 0; i < 5;i++){
geometricObjects[i] = new Square();
((Square)geometricObjects[i]).setCanbecolored(random.nextBoolean());
}
for(int i = 0; i < 5;i++){
System.out.println("第" + (i+1) + "个对象");
if(((Square)geometricObjects[i]).getCanbecolor()){
((Square)geometricObjects[i]).howToColor();
}
else System.out.println("不可着色");
}
}
}
(4)experiment4:附加题
Max类
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;
public class Max {
public static Object max(Comparable[] a){
if(a[0] instanceof String){
String max = (String)a[0];
for(int i = 1; i < a.length;i++){
if(a[i].compareTo(max) > 0)max = (String)a[i];
}
return max;
}
if(a[0] instanceof Date){
Date max = (Date)a[0];
for(int i = 1;i < a.length;i++){
if(a[i].compareTo(max) > 0)max = (Date)a[i];
}
return max;
}
if(a[0] instanceof Integer){
int max = (Integer)a[0];
for(int i = 1;i < a.length;i++){
if(a[i].compareTo(max) > 0)max = (Integer)a[i];
}
return max;
}
return null;
}
public static void main(String[] args) throws ParseException {
Scanner input = new Scanner(System.in);
Integer[] num = new Integer[10];
String[] strings = new String[10];
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
Date[] dates = new Date[10];
System.out.println("请输入十个整数: ");
for(int i = 0; i < 10;i++){
num[i] = input.nextInt();
}
System.out.println("请输入十个字符串: ");
for(int i = 0; i < 10;i++){
strings[i] = input.next();
}
System.out.println("请输入十个时间: ");
for(int i = 0; i < 10;i++){
dates[i] = new Date();
dates[i] = simpleDateFormat.parse(input.next());
}
input.close();
int max1 = (int)max(num);
String max2 = (String)max(strings);
Date max3 = (Date)max(dates);
System.out.println("最大整数为: " + max1);
System.out.println("最大字符串为: " + max2);
System.out.println("最大日期为: " + max3);
}
}