中南大学计算机学院实验报告
课程名称 Java面向对象程序设计SSD3
实验项目名称 实验3《对象和类》
学生姓名 Xi_Chen123 专业班级 ******班 学号 **********
实验成绩 日期
实验学时: 2
每组人数: 1
实验类型: 1 (1:基础性 2:综合性 3:设计性 4:研究性)
实验要求: 1 (1:必修 2:选修 3:其它)
实验类别: 2 (1:基础 2:专业基础 3:专业 4:其它)
- 实验目的
- 设计类,并画出UML类图
- 实现UML中的类
- 使用类开发应用程序
二、实验内容
1、(P305, 9.1)【矩形类Rectangle】遵照9.2节中Circle类的例子,设计一个名为Rectangle的类表示矩形。这个类包括:
- 两个名为width和height的double型数据域,它们分别表示矩形的宽和高。width和height的默认值都为1。
- 创建默认矩形的无参构造方法。
- 创建width和height为指定值的矩形的构造方法。
- 一个名为getArea()的方法返回这个矩形的面积。
- 一个名为getPerimeter()的方法返回矩形周长。
画出该类的UML图并实现这个类。编写一个测试程序,创建两个Rectangle对象:一个矩形的宽为4高为40,另一个矩形的宽为3.5高为35.9。依次显示每个矩形的宽、高、面积和周长。
2. (P307, 9.8)【风扇类Fan】设计一个名为Fan的类表示一个风扇。这个类包括:
- 三个名为SLOW、MEDIUM和FAST而值为1、2、3的常量表示风扇的速度。
- 一个名为speed的int类型私有数据域表示风扇的速度(默认值为SLOW)。
- 一个名为on的boolean类型私有数据域表示风扇是否打开(默认值为false)。
- 一个名为radius的double类型私有数据域表示风扇的半径(默认值为5)。
- 一个名为color的String类型私有数据域表示风扇的颜色(默认值为blue)。
- 这四个数据域的访问器和修改器。
- 一个创建默认风扇的无参构造方法。
- 一个名为toString()的方法返回描述风扇的字符串。如果风扇是打开的,那么该方法在一个组合的字符串中返回风扇的速度、颜色和半径。如果风扇没有打开,该方法返回一个由“fan is off”和风扇颜色、半径组成的字符串。
画出该类的UML图。实现这个类。编写一个测试程序,创建两个Fan对象。将第一个对象设置为最大速度、半径为10、颜色为yellow、状态为打开。将第二个对象设置为中等速度、半径为5、颜色为blue、状态为关闭。通过调用它们的toString方法显示这些对象。
3.(P308,9.10*)【二次方程式】为二次方程式ax2+bx+c=0设计一个名为QuadraticEquation的类。这个类包括:
- 代表三个系数的私有数据域a、b、c。
- 一个参数为a、b、c的构造方法。
- a、b、c的三个get方法。
- 一个名为getDiscriminant()的方法返回判别式,b2-4ac。
- 一个名为getRoot1()和getRoot2()的方法返回等式的两个根。
这些方法只有在判别式为非负数时才有用。如果判别式为负,方法返回0。
画出该类的UML图。实现这个类。编写一个测试程序,提示用户输入a、b、c的值,然后显示判别式的结果。如果判别式为正数,显示两个根;如果判别式为0,显示一个根;否则,显示“The equation has no roots”。
4.(P308, 9.13**)【位置类】设计一个名为Location的类,定位二维数组中的最大值及其位置。这个类包括公共的数据域row、column和maxValue,二维数组中的最大值及其下标用double型的maxValue以及int型的row和column存储。
编写下面的方法,返回一个二维数组中最大值的位置。
public static Location locateLargetst(double[][] a)
返回值是一个Location的实例。编写一个测试程序,提示用户输入一个二维数组,然后显示这个数组中的最大元素及下标。运行实例如下:
输入二维数组的行数和列数: 3 4
输入数组:
23.5 35 2 10
4.5 3 45 3.5
35 44 5.5 9.6
最大元素及其下标是: 45 在(1,2)
要求每个学生独立完成实验任务。
四、实验报告
1.在一周内完成本项目实验,在可视化平台上提交实验文档,包括:4个.java文件(分别对应以上4道题,不需要.class文件)打包成一个名为“实验3”的.rar或.zip文件,以及实验报告1份(格式与要求见下),报告命名为“班级名(如“2101”)_学号_姓名_实验3.doc”。
2. 实验结果与分析
(包括运行结果截图、结果分析等)
实验一
实验二
实验三
实验四
3. 心得体会
(记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。)
本次实验的难度略有提升,在编写过程中也有了较多的阻碍和小困难。在查询资料和与同学进行讨论之后,也都得到了较为合理的解决方案。
在编写实验一的过程中,整体较为顺利。在输出结果的过程中,由于double类型在计算过程中会产生精度损失,输出时非常难看,所以采用创建DecimalFormat实例的方法来对数据进行处理后再输出就可以得到正确的结果。
在编写实验二的过程中,最开始是打算分为两个文件进行编写,其中一个class单纯为Fan的类,另一个class为FanDemo,编写main函数对Fan进行输出。由于本次实验需要添加最终静态数据类型,该类型无法跨文件进行使用,所以最后放弃了这个想法,索性直接编写到同一个class中了。
实验三较为繁琐,但并不困难,最核心的思想就是将我们熟悉的公式用程序语言进行合理表达,把握好运算的优先级与括号省略规则就可以轻松编译。在完成了实验三的全部功能后,本以为万事大吉,然而程序却进行了警告:
(警告信息如下)
原因是在程序中没有使用get函数来获取a、b、c的值,因为在这个实验中,main函数和QuadraticEquation编写在同一个类中,可以直接调用私有数据成员,于是这三个get方法就被闲置下来,产生警告。于是我将该文件拆分成了两个类,使得get方法被“强行”使用了,解决了这个警告。
在编写实验四的过程中,第一个较为陌生的知识就是二维数组。二维数组是通过通过两个维度来找到数组中对应的元素,在平时存储数据中较为少见,但在平面图、行列式、矩阵等方面使用较多。首先就是在对二维数组中录入数据的过程,如何达到图例中那样按照行与列的形式输入呢?我使用了Scanner中的实例调用的方法next(),其好处在于空格键和回车键都可以作为元素分割的标识符,缺点在于分割的元素为String类型,无法直接存储到double类型的数组中。所以我再运用了Double类中的double parseDouble(String s);方法,将录入的String元素转化为double类型。部分程序如下:
第二个就是对于二维数组的遍历,我们该如何按照行与列逐个遍历二维数组呢?通过网络查询与同学交流,我知道了如下信息:二维数组的数组名可以调用length方法,获取二维数组的行数,譬如:num.length;在第i行,二维数组的数组名+[i]可以调用length方法,获取该行的列数,譬如:num[i].length。参考程序如下:
总而言之,本次实验难度略有提升,还有一部分问题是对类与对象的使用还是有些生疏,比如编写出了出现警告的程序。在日后的学习中还需要继续加强和改进,继续练习相关的程序题目,达到更高层次的编程水平
4.【附源程序】(除了单独的.java文件,也请复制到实验文档里,方便批阅者评阅)
实验一
package com.xc3;
import java.text.DecimalFormat;
public class Rectangle {
private double width=1;
private double height=1;
//无参构造方法
public Rectangle(){
}
//带参构造方法
public Rectangle(double width,double height){
this.height=height;
this.width=width;
}
//获取width
public double getWidth(){
return width;
}
//获取height
public double getHeight(){
return height;
}
//获取area
public double getArea(){
return height*width;
}
//获取perimeter
public double getPerimeter(){
return 2*(height+width);
}
public static void main(String[] args) {
//创建两个Rectangle对象
Rectangle r1=new Rectangle(4,40);
Rectangle r2=new Rectangle(3.5,35.9);
//显示结果
DecimalFormat df=new DecimalFormat("0.00");
System.out.println("width:"+r1.getWidth()+" height:"+r1.getHeight()+" area:"+r1.getArea()+" perimeter:"+r1.getPerimeter());
System.out.println("width:"+r2.getWidth()+" height:"+r2.getHeight()+" area:"+df.format(r2.getArea())+" perimeter:"+df.format(r2.getPerimeter()));
}
}
实验二
package com.xc3;
public class Fan {
final static int SLOW=1;
final static int MEDIUM=2;
final static int FAST=3;
private int speed=SLOW;
private boolean on=false;
private double radius=5;
private String color="blue";
public Fan() {
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isOn() {
return on;
}
public void setOn(boolean on) {
this.on = on;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String toString() {
if (isOn()) {
return "The speed of the fan is " + getSpeed() + ", the radius of the fan is " + getRadius() + ", the color of the fan is " + getColor();
} else {
return "The fan is off";
}
}
//main
public static void main(String[] args) {
//创建对象
Fan f1=new Fan();
Fan f2=new Fan();
//设置对象
f1.setSpeed(FAST);
f1.setRadius(10);
f1.setColor("yellow");
f1.setOn(true);
f2.setSpeed(MEDIUM);
f2.setRadius(5);
f2.setColor("blue");
f2.setOn(false);
//显示对象
System.out.println(f1.toString());
System.out.println(f2.toString());
}
}
实验三
QuadraticEquation类
package com.xc3.QE;
public class QuadraticEquation {
private double a;
private double b;
private double c;
public QuadraticEquation() {
}
public QuadraticEquation(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
public double getA() {
return a;
}
public double getB() {
return b;
}
public double getC() {
return c;
}
public double getDiscriminant(){
return b * b - 4 * a * c;
}
public double getRoot1(){
if(getDiscriminant()>=0) {
return (-1 * b + Math.sqrt(b * b - 4 * a * c)) / 2 * a;
}
return 0;
}
public double getRoot2(){
if(getDiscriminant()>=0) {
return (-1 * b - Math.sqrt(b * b - 4 * a * c)) / 2 * a;
}
return 0;
}
}
QuadraticEquationDemo类
package com.xc3.QE;
import java.util.Scanner;
public class QuadraticEquationDemo {
public static void main(String[] args) {
//输入数据
System.out.println("Please input the a,b,c of the number.");
Scanner sc=new Scanner(System.in);
double a=sc.nextDouble();
double b=sc.nextDouble();
double c=sc.nextDouble();
QuadraticEquation qe=new QuadraticEquation(a,b,c);
//显示判别式结果
double result=qe.getDiscriminant();
System.out.println("The result of Discriminant is: "+result);
//显示结果
if(result<0){
//若判别式小于0
System.out.println("The equation has no roots");
}else if(result==0){
//若判别式等于0
System.out.println("The result of root is: "+qe.getRoot1());
}else{
//若判别式大于0
System.out.println("The result of root1 is: "+qe.getRoot1()+", the root2 is: "+qe.getRoot2());
}
}
}
实验四
package com.xc3;
import java.util.Scanner;
public class Location {
private int row;
private int colum;
private double maxValue;
public Location() {
}
public Location(int row, int colum, double maxValue) {
this.row = row;
this.colum = colum;
this.maxValue = maxValue;
}
public int getRow() {
return row;
}
public int getColum() {
return colum;
}
public double getMaxValue() {
return maxValue;
}
public static void main(String[] args) {
//输入行数和列数
System.out.print("请输入二维数组的行数和列数:");
Scanner sc=new Scanner(System.in);
int row=sc.nextInt();
int colum=sc.nextInt();
//创建数组并输入数据
System.out.println("输入数组:");
double[][] num=new double[row][colum];
for(int i=0;i<row;i++){
for(int j=0;j<colum;j++){
num[i][j]=Double.parseDouble(sc.next());
}
}
//计算数据
Location l=locateLargest(num);
//输出结果
System.out.print("最大元素及其下标是:"+l.getMaxValue()+" 在("+l.getRow()+","+l.getColum()+")");
}
public static Location locateLargest(double[][] a){
int row=0;
int colum=0;
double maxValue=a[row][colum];
for(int i=0;i<a.length;i++){
for(int j=0;j<a[i].length;j++){
if(a[i][j]>maxValue){
maxValue=a[i][j];
row=i;
colum=j;
}
}
}
return new Location(row,colum,maxValue);
}
}