实验题目
现实生活中,底部图形与高决定了某个椎体,其是矩形棱椎体、三棱椎体,还是圆锥。请编写程序,能够显示出不同图形的具体参数(矩形:长、宽;三角形:三边长度;圆:半径),及其面积与周长,并求出由不同图形组成椎体的底面积和体积。
(1)编写一抽象类(shape),长方形类、三角形类与圆类均为其子类,并各有各的属性。其中父类有获得其周长、面积的方法。然后在一测试类中,分别建立若干个子对象,并分别将这些对象的面积与周长统计输出。
(2)在上述基础上,编写锥体,包括下底和高,求下底分别为长方形,三角形,圆形的椎体体积。控制台效果如下:
(要求:格式化输出椎体积,从左保留5位数,包含小数点后2位;使用向上转型对象)
(3)控制台运行结果:
实验环境:
eclipse的版本: Mars.2 Release (4.5.2)
电脑系统:Windows 11
JDK版本:1.8.0_261
实验步骤:
1.首先创建一个抽象Shape类,然后写出两个抽象方法area和perimeter,用来计算面积和周长。
2.创建一个抽象的矩形Rectangle类,初始化定义它的长和宽,然后重写父类Shape类里面的面积和周长的方法,并且返回面积和周长的计算公式。
3.创建一个抽象的三角形Triangle类,初始化定义它的三边长,然后重写父类Shape类里面的面积和周长的方法,并且返回面积和周长的计算公式,面积用海伦公式计算。
4.创建一个抽象的Cicle类,初始化定义它的半径长,然后重写父类Shape类里面的面积和周长的方法,并且返回面积和周长的计算公式。
5.创建一个锥形Cone类,定义一个Shape类型的shape成员变量,用这个变量来调用各个图形的面积作为计算锥形体积的底,再定义一个高和锥形的名字,并且初始化。然后构造一个方法,返回体积的计算公式。
6.创建一个主类Test,以Rectangle类的输出为例:创建一个Rectangle的对象,将这个赋值给rectangle变量,其中把矩形的长和宽的参数传进去,这样就可以输出矩形长和宽的值,用rectangle调用长和宽就行。输出周长和面积的时候,也是这样调用面积和周长就行,但是要用格式化输出的形式来实现。
8.在上述的基础上,要计算以矩形为底的锥形的体积时,要创建一个Cone对象cone,然后将Shape类型的参数,高,已经这个形状的名字作为参数传递到里面,所以在格式化输出体积时,用这个cone对象调用体积就行。
9.剩下的圆和三角形和上面的处理方法一样。
实验源代码(带注释):
Test.Java:
public class Test {
public static void main(String[] args) {
//shape是一个上转型对象,将Rectangle、Triangle、Cicle对象赋值给Shape类型的变量shape。
Shape shape;
//创建了一个Rectangle对象,并将其赋值给rectangle变量。其中3.00表示矩形的长,4.00表示矩形的宽。
Rectangle rectangle = new Rectangle(3.00, 4.00);
//rectangle.length:表示一个矩形对象(rectangle)的长。
System.out.println("矩形的长为"+rectangle.length+','+"宽为"+rectangle.wide);
//格式化输出矩形的周长和面积。
System.out.printf("矩形的周长为:%5.2f,面积为:%5.2f",rectangle.perimeter(),rectangle.area());
//换行
System.out.println("");
//由于Rectangle是Shape的子类,将rectangle对象赋值给shape变量。
shape = rectangle;
//创建了一个Cone对象,传入一个Shape类型的参数、一个double类型的高度参数和一个字符串类型的锥体名称参数。
Cone cone = new Cone(shape, 3.00,"矩形");
//格式化输出锥的底面积,高和体积。
//rectangle.area():表示调用一个名为 area 的方法来计算一个矩形对象(rectangle)的面积。
System.out.printf("底面积%5.2f,高为%.2f的%s锥,体积为:%-5.2f",rectangle.area(),cone.height,cone.coneName,cone.V());
//换行
System.out.println("");
System.out.println("");
//创建了一个Triangle对象,并将其赋值给triangle变量。其中3.0,4.0,5.0表示三角形的三边长。
Triangle triangle = new Triangle(3.0, 4.0, 5.0);
//triangle.a:表示一个三角形对象(triangle)的边的长度
System.out.println("三角形的三边长为:"+triangle.a+'、'+triangle.b+'、'+triangle.c);
//格式化输出三角形的周长和面积。
System.out.printf("三角形的周长为:%5.2f,面积为:%5.2f",triangle.perimeter(),triangle.area());
//换行
System.out.println("");
System.out.println("");
//将triangle对象赋值给shape变量。
shape = triangle;
Cone cone1 = new Cone(shape, 3.00,"三角形");
//triangle.area():表示调用一个名为 area 的方法来计算一个三角形对象(triangle)的面积。
System.out.printf("底面积%5.2f,高为%.2f的%s锥,体积为:%-5.2f",triangle.area(),cone1.height,cone1.coneName,cone1.V());
System.out.println("");
//创建了一个Cicle对象,并将其赋值给cicle变量。其中3.0表示圆的半径。
Cicle cicle = new Cicle(3.0);
//cicle.r:表示圆对象(cicle)的半径长。
System.out.println("圆的半径为:"+cicle.r);
//格式化输出圆的周长和面积。
System.out.printf("圆的周长为:%5.2f,面积为:%5.2f",cicle.perimeter(),cicle.area());
//换行。
System.out.println("");
System.out.println("");
//将cicle对象赋值给shape变量。
shape = cicle;
Cone cone2 = new Cone(shape, 3.00,"圆");
//cicle.area():表示调用一个名为 area 的方法来计算圆对象(cicle)的面积。
System.out.printf("底面积:%5.2f, 高为%.2f的%s锥, 体积为:%-5.2f", cicle.area(), cone2.height, cone2.coneName, cone2.V());
}
}
Shape.java:
public abstract class Shape {
//写了两个方法,表示面积area和周长perimeter。
public abstract double area();
public abstract double perimeter();
}
Rectangle.java:
public class Rectangle extends Shape{
//定义double类型的成员变量length和wide,表示矩形的长和宽。
double length;
double wide;
//构造函数Rectangle(double length,double wide),用于初始化矩形的长和宽。
public Rectangle(double length,double wide){
this.length= length;
this.wide = wide;
}
//重写了Shape的area方法,返回值为矩形的面积。
@Override
public double area() {
// TODO Auto-generated method stub
return length*wide;
}
//重写了Shape的perimeter方法,返回值为矩形的周长。
@Override
public double perimeter() {
// TODO Auto-generated method stub
return 2*(length+wide);
}
}
Triangle.java:
public class Triangle extends Shape {
//定义double类型的成员变量a,b,c表示三角形的三边长。
double a;
double b;
double c;
//构造函数Triangle (double a,double b,double c),用于初始化三角形的三边长。
public Triangle (double a,double b,double c) {
this.a = a;
this.b = b;
this.c = c;
}
//重写了Shape的area方法,返回值为三角形的面积,这个用海伦公式计算。
@Override
public double area() {
// TODO Auto-generated method stub
double p = (a+b+c)*0.5;
return Math.sqrt(p*(p-a)*(p-b)*(p-c));
}
//重写了Shape的perimeter方法,返回值为三角形的周长。
@Override
public double perimeter() {
// TODO Auto-generated method stub
return a+b+c;
}
}
Cone.java:
public class Cone {
//定义了一个名为shape的成员变量,该成员变量的类型为Shape。Shape是接口,它定义了一些形状的基本属性和方法。
//在Cone类中,shape成员变量的作用是表示圆锥底面积的形状,可以通过调用shape的方法来获取锥形的底面积形状。
Shape shape;
//定义圆锥的高为double型,名字为String型。
double height;
String coneName;
//构造函数Cone (Shape shape,double height,String coneName),用于初始化锥形的形状,高和名字。
public Cone (Shape shape,double height,String coneName) {
this.shape = shape;
this.coneName = coneName;
this.height = height;
}
//构造了一个方法,表示锥形的体积,返回值为锥形的体积计算公式。
public double V() {
return (shape.area()*height)*1/3;
}
}
Cicle.java:
public class Cicle extends Shape{
//定义一个double类型的成员变量r,表示圆的半径
double r;
//构造函数Cicle(double r)用于初始化圆的半径
public Cicle (double r) {
this.r = r;
}
//重写Shape中的两个方法,该方法返回圆的面积和周长
@Override
public double area() {
// TODO Auto-generated method stub
//PI是Math的静态属性
return Math.PI*r*r;
}
@Override
public double perimeter() {
// TODO Auto-generated method stub
return 2*r*Math.PI;
}
}
另一种方法:我们可以用抽象类来实现这个题目的输出,用接口:
Shape.java代码如下:
public interface Shape {
//写了两个方法,表示面积area和周长perimeter。
public double area();
public double perimeter();
}
Test.java代码如下:
public class Test {
public static void main(String[] args) {
//shape是一个上转型对象,将Rectangle、Triangle、Cicle对象赋值给Shape类型的变量shape,实现了多态性。
Shape shape;
//创建了一个Rectangle对象,并将其赋值给rectangle变量。其中3.00表示矩形的长,4.00表示矩形的宽。
Rectangle rectangle = new Rectangle(3.00, 4.00);
//rectangle.length:表示一个矩形对象(rectangle)的长。
System.out.println("矩形的长为"+rectangle.length+','+"宽为"+rectangle.wide);
//格式化输出矩形的周长和面积。
System.out.printf("矩形的周长为:%5.2f,面积为:%5.2f",rectangle.perimeter(),rectangle.area());
//换行
System.out.println("");
//由于Rectangle是Shape的子类,将rectangle对象赋值给shape变量。
shape = rectangle;
//创建了一个Cone对象,传入一个Shape类型的参数、一个double类型的高度参数和一个字符串类型的锥体名称参数。
Cone cone = new Cone(shape, 3.00,"矩形");
//格式化输出圆锥的底面积,高和体积。
//rectangle.area():表示调用一个名为 area 的方法来计算一个矩形对象(rectangle)的面积。
System.out.printf("底面积%5.2f,高为%.2f的%s锥,体积为:%-5.2f",rectangle.area(),cone.height,cone.coneName,cone.V());
//换行
System.out.println("");
//创建了一个Triangle对象,并将其赋值给triangle变量。其中3.0,4.0,5.0表示三角形的三边长。
Triangle triangle = new Triangle(3.0, 4.0, 5.0);
//triangle.a:表示一个三角形对象(triangle)的边的长度
System.out.println("三角形的三边长为:"+triangle.a+'、'+triangle.b+'、'+triangle.c);
//格式化输出三角形的周长和面积。
System.out.printf("三角形的周长为:%5.2f,面积为:%5.2f",triangle.perimeter(),triangle.area());
//换行。
System.out.println("");
//将triangle对象赋值给shape变量。
shape = triangle;
Cone cone1 = new Cone(shape, 3.00,"三角形");
//triangle.area():表示调用一个名为 area 的方法来计算一个三角形对象(triangle)的面积。
System.out.printf("底面积%5.2f,高为%.2f的%s锥,体积为:%-5.2f",triangle.area(),cone1.height,cone1.coneName,cone1.V());
//创建了一个Cicle对象,并将其赋值给cicle变量。其中3.0表示圆的半径。
Cicle cicle = new Cicle(3.0);
//cicle.r:表示圆对象(cicle)的半径长。
System.out.println("圆的半径为:"+cicle.r);
//格式化输出圆的周长和面积。
System.out.printf("圆的周长为:%5.2f,面积为:%5.2f",cicle.perimeter(),cicle.area());
//换行。
System.out.println("");
//将cicle对象赋值给shape变量。
shape = cicle;
Cone cone2 = new Cone(shape, 3.00,"圆");
//cicle.area():表示调用一个名为 area 的方法来计算圆对象(cicle)的面积。
System.out.printf("底面积:%5.2f, 高为%.2f的%s锥, 体积为:%-5.2f", cicle.area(), cone2.height, cone2.coneName, cone2.V());
}
}
Triangle.java代码如下:
public class Triangle implements Shape {
//定义double类型的成员变量a,b,c表示三角形的三边长。
double a;
double b;
double c;
//构造函数Triangle (double a,double b,double c),用于初始化三角形的三边长。
public Triangle (double a,double b,double c) {
this.a = a;
this.b = b;
this.c = c;
}
//重写了Shape的area方法,返回值为三角形的面积,这个用海伦公式计算。
@Override
public double area() {
// TODO Auto-generated method stub
double p = (a+b+c)*0.5;
return Math.sqrt(p*(p-a)*(p-b)*(p-c));
}
//重写了Shape的perimeter方法,返回值为三角形的周长。
@Override
public double perimeter() {
// TODO Auto-generated method stub
return a+b+c;
}
}
Rectangle.java代码如下:
public class Rectangle implements Shape{
//定义double类型的成员变量length和wide,表示矩形的长和宽。
double length;
double wide;
//构造函数Rectangle(double length,double wide),用于初始化矩形的长和宽。
public Rectangle(double length,double wide){
this.length= length;
this.wide = wide;
}
//重写了Shape的area方法,返回值为矩形的面积。
@Override
public double area() {
// TODO Auto-generated method stub
return length*wide;
}
//重写了Shape的perimeter方法,返回值为矩形的周长。
@Override
public double perimeter() {
// TODO Auto-generated method stub
return 2*(length+wide);
}
}
Cone.java代码如下:
public class Cone {
//定义了一个名为shape的成员变量,该成员变量的类型为Shape。Shape是接口,它定义了一些形状的基本属性和方法。
//在Cone类中,shape成员变量的作用是表示圆锥底面积的形状,可以通过调用shape的方法来获取锥形的底面积形状。
Shape shape;
//定义圆锥的高为double型,名字为String型。
double height;
String coneName;
//构造函数Cone (Shape shape,double height,String coneName),用于初始化锥形的形状,高和名字。
public Cone (Shape shape,double height,String coneName) {
this.shape = shape;
this.coneName = coneName;
this.height = height;
}
//构造了一个方法,表示锥形的体积,返回值为锥形的体积计算公式。
public double V() {
return (shape.area()*height)*1/3;
}
}
Cicle.java代码如下:
public class Cicle implements Shape{
//定义一个double类型的成员变量r,表示圆的半径
double r;
//构造函数Cicle(double r)用于初始化圆的半径
public Cicle (double r) {
this.r = r;
}
//重写Shape中的两个方法,该方法返回圆的面积和周长
@Override
public double area() {
// TODO Auto-generated method stub
//PI是Math的静态属性
return Math.PI*r*r;
}
@Override
public double perimeter() {
// TODO Auto-generated method stub
return 2*r*Math.PI;
}
}
实验小结:
1.什么是上转型对象?
先找到了上转型的例子进行理解:
例如B是A的子类,当用子类B创建一个对象,并把这个对象的引用放到A类声明的对象a中时,
A a;
a=new B();
那么就称对象a是子类对象b的上转型对象,明白了上转型对象是将子类的对象赋值给父类,就是父类可以调用子类里面的方法。
2.成员变量和局部变量的区别,以及this关键字怎么用?
成员方法定义在类里面,而局部变量是在方法形参,方法体或者代码快中。在下面的例子中,this.goods中的goods就是成员变量,后面的goods是方法的参数,所以他就是局部变量。而this关键字就是来解决局部变量和成员变量重名的问题,如果重名了,但是又需要用到这个变量名,就需要调用this这个关键字。
eg:
this.goods = goods;
3.如何进行格式化输出?
使用printf函数可以将输出的内容格式化为指定的字符串格式。用逗号而不是加号的原因是,printf函数的参数是可变参数,即可以传入任意数量的参数,逗号就用来分割不同的参数,加号是只能用来连接字符串的。并且进行格式化输出时候还有另外的三种方法,System.out.format(),Fomatter类,String.format()。
4.在计算锥形的体积的时候,怎么样来调用矩形,三角形,圆的面积?
创建一个Shape类的shape对象,然后将Rectangle、Triangle、Cicle对象赋值给Shape类型的变量shape。以矩形为底的锥形举例,在这个里面创建Rectangle的对象rectangle,将长和宽的值传给rectangle,将rectangle对象赋值给shape。接着创建的Cone类,在这个类中将shape作为参数,然后传给Cone的对象cone,最后用cone调用Cone中计算体积的方法。