题目描述
设计一个几何图形的面积与周长计算程序。要求如下:
- 定义一个图形接口,里面存放计算面积和周长的抽象方法。
- 创建圆形类、矩形类、椭圆、正方形、三角形对图形接口的实现,其中圆继承于椭圆,正方形继承于长方形,并在各子类中定义求周长和面积的方法。 (子类)
- 主函数实现如下功能:
- 长方形
- 正方形
- 圆
- 椭圆
- 三角形
- 按周长从大到小排序输出图形
- 按面积从小到大排序输出图形
- 随机输出所有图形
- 查看所有图形
- 删除图形
- 推出程序
设计思路
首先看下类图
首先定义一个图形接口
图形接口中有设置周长setPerimeter()
、设置面积setArea()
、获取周长getPerimeter()
、获取面积getArea()
获取图形idgetSign()
方法。
public interface IShape {
/**
* 计算周长
*/
void setPerimeter();
/**
* 计算面积
*/
void setArea();
/**
* 获取id
*
* @return id
*/
Integer getSign();
/**
* 获取周长
*
* @return 周长
*/
Double getPerimeter();
/**
* 获取面积
*
* @return 面积
*/
Double getArea();
}
定义一个图形抽象类
定义一个图形抽象类(BaseObject)实现图形接口(IShape),其中中定义周长和面接,实现获取面积getArea()
和获取周长getPerimeter()
方法。
public abstract class BaseObject implements IShape {
/**
* 周长
*/
protected BigDecimal perimeter;
/**
* 面积
*/
protected BigDecimal area;
@Override
public Double getArea() {
return area.doubleValue();
}
@Override
public Double getPerimeter() {
return perimeter.doubleValue();
}
}
定义一个常量
定义一个常量来记录有图形,其中记录name
和id
属性,其中id属性用来将相同的图形一同输出。
public enum Shape {
/**
* 长方形
*/
RECTANGLE("长方形", 1),
TRILATERAL("三角形", 2),
ELLIPSE("椭圆", 3),
ROUNDNESS("圆形", 4),
SQUARE("正方形", 5);
private String name;
private Integer id;
Shape(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public Integer getId() {
return id;
}
}
定义长方形
public class Rectangle extends BaseObject {
private static final Integer SIGN = Shape.RECTANGLE.getId();
private BigDecimal length;
private BigDecimal width;
public Rectangle() {
}
public Rectangle(String width, String length) {
this.width = new BigDecimal(width);
this.length = new BigDecimal(length);
}
@Override
public Integer getSign() {
return SIGN;
}
@Override
public void setPerimeter() {
if (Objects.isNull(width) && Objects.isNull(length)) return;
super.perimeter = width.add(length).multiply(new BigDecimal("2"));
}
@Override
public void setArea() {
if (Objects.isNull(width) && Objects.isNull(length)) return;
super.area = width.multiply(length);
}
@Override
public String toString() {
return Shape.RECTANGLE.getName() + "{" +
"宽=" + width +
", 长=" + length +
", 周长=" + perimeter +
", 面积=" + area +
"}";
}
}
定义正方形
public class Square extends Rectangle {
private static final Integer SIGN = Shape.SQUARE.getId();
private BigDecimal side;
public Square(String side) {
this.side = new BigDecimal(side);
}
@Override
public Integer getSign() {
return SIGN;
}
@Override
public void setPerimeter() {
super.perimeter = side.multiply(new BigDecimal("4"));
}
@Override
public void setArea() {
super.area = side.multiply(side);
}
@Override
public String toString() {
return Shape.SQUARE.getName() + "{" +
"边长=" + side +
", 周长=" + perimeter +
", 面积=" + area +
"}\n";
}
}
定义椭圆
public class Ellipse extends BaseObject {
private static final Integer SIGN = Shape.ELLIPSE.getId();
private BigDecimal longRadius;
private BigDecimal shortRadius;
public Ellipse() {
}
public Ellipse(String longRadius, String shorRadius) {
this.longRadius = new BigDecimal(longRadius);
this.shortRadius = new BigDecimal(shorRadius);
}
@Override
public void setPerimeter() {
BigDecimal once = shortRadius.multiply(BigDecimal.valueOf(2)).multiply(new BigDecimal(Math.PI));
BigDecimal twice = longRadius.subtract(shortRadius).multiply(BigDecimal.valueOf(4));
super.perimeter = once.add(twice).setScale(5, RoundingMode.HALF_UP);
}
@Override
public void setArea() {
super.area = longRadius.multiply(shortRadius).multiply(new BigDecimal(Math.PI)).setScale(5, RoundingMode.HALF_UP);
}
@Override
public Integer getSign() {
return SIGN;
}
@Override
public String toString() {
return Shape.ELLIPSE.getName() + "{" + "长半径=" + longRadius + ", 短半径=" + shortRadius + ", 周长=" + perimeter + ", 面积=" + area + '}';
}
}
定义圆
public class Roundness extends Ellipse {
private static final Integer SIGN = Shape.ROUNDNESS.getId();
private BigDecimal radius;
public Roundness(String radius) {
this.radius = new BigDecimal(radius);
}
@Override
public Integer getSign() {
return SIGN;
}
@Override
public void setPerimeter() {
super.perimeter = radius.multiply(BigDecimal.valueOf(2))
.multiply(new BigDecimal(String.valueOf(Math.PI)))
.setScale(5, RoundingMode.HALF_UP);
}
@Override
public void setArea() {
super.area = radius
.multiply(radius)
.multiply(new BigDecimal(String.valueOf(Math.PI)))
.setScale(5, RoundingMode.HALF_UP);
}
@Override
public String toString() {
return Shape.ROUNDNESS.getName() + "{" + "半径=" + radius + ", 周长=" + perimeter + ", 面积=" + area + '}';
}
}
定义三角形
public class Trilateral extends BaseObject {
private final Integer SIGN = Shape.TRILATERAL.getId();
private BigDecimal one;
private BigDecimal two;
private BigDecimal tree;
public Trilateral(String one, String two, String tree) {
this.tree = new BigDecimal(tree);
this.one = new BigDecimal(one);
this.two = new BigDecimal(two);
}
@Override
public void setPerimeter() {
super.perimeter = one.add(tree).add(two);
}
@Override
public void setArea() {
BigDecimal p = one.add(tree).add(two).divide(BigDecimal.valueOf(2L), RoundingMode.HALF_UP);
BigDecimal newOne = p.subtract(one);
BigDecimal newTwo = p.subtract(one);
BigDecimal newThree = p.subtract(one);
double v = p.multiply(newOne).multiply(newThree).multiply(newTwo).doubleValue();
String temp = String.valueOf(Math.sqrt(v));
super.area = new BigDecimal(temp);
}
@Override
public Integer getSign() {
return SIGN;
}
@Override
public String toString() {
return Shape.TRILATERAL.getName() + "{" + "边1=" + one + ", 边2=" + two + ", 边3=" + tree + ", 周长=" + perimeter + ", 面积=" + area + '}';
}
}
公共类
public class CalculateUtils {
public static List<IShape> list = new ArrayList<>(16);
/**
* 计算长方形
*
* @param input 字符输入
*/
public static void calculateRectangle(String input) {
String[] arr = splitStr(input);
if (arr.length != 2) throw new RuntimeException("输入不合法");
IShape rectangle = new Rectangle(arr[0], arr[1]);
rectangle.setPerimeter();
rectangle.setArea();
System.out.println(rectangle);
list.add(rectangle);
}
/**
* 计算正方形
*
* @param input 字符输入
*/
public static void calculateSquare(String input) {
String[] arr = splitStr(input);
IShape square = new Square(arr[0]);
square.setPerimeter();
square.setArea();
System.out.println(square);
list.add(square);
}
public static void calculateRoundness(String input) {
String[] arr = splitStr(input);
Roundness roundness = new Roundness(arr[0]);
roundness.setArea();
roundness.setPerimeter();
System.out.println(roundness);
list.add(roundness);
}
public static void calculateEllipse(String input) {
String[] arr = splitStr(input);
if (arr.length != 2) throw new RuntimeException("输入不合法");
Arrays.sort(arr);
IShape ellipse = new Ellipse(arr[1], arr[0]);
ellipse.setArea();
ellipse.setPerimeter();
System.out.println(ellipse);
list.add(ellipse);
}
/**
* 计算三角形
*
* @param input 输入
*/
public static void calculateTrilateral(String input) {
System.out.println(input);
String[] arr = splitStr(input);
if (arr.length != 3) throw new RuntimeException("输入不合法");
if (!isTrilateral(arr)) throw new RuntimeException("输入不合法");
Trilateral trilateral = new Trilateral(arr[0], arr[1], arr[2]);
trilateral.setArea();
trilateral.setPerimeter();
System.out.println(trilateral);
list.add(trilateral);
}
public static boolean isTrilateral(String[] arr) {
Double a = Double.valueOf(arr[0]);
Double b = Double.valueOf(arr[1]);
Double c = Double.valueOf(arr[2]);
return a + b > c && a + c > b && b + c > a;
}
public static String[] splitStr(String s) {
if (s == null) throw new RuntimeException("输入不能为空");
return s.split(" ");
}
}
运行类
public class ComputingSystem {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
printMenu();
int temp = 0;
try {
temp = sc.nextInt();
} catch (Exception e) {
e.printStackTrace();
}
if (temp == 0) break;
sys(temp);
}
}
public static void sys(int choose) {
Scanner sc = new Scanner(System.in);
String s = null;
switch (choose) {
case 1:
System.out.println("请输入长方形的长宽 例: 10 20");
s = sc.nextLine().trim();
CalculateUtils.calculateRectangle(s);
break;
case 2:
System.out.println("请输入正方形的边长 例: 10");
s = sc.nextLine().trim();
CalculateUtils.calculateSquare(s);
break;
case 3:
System.out.println("请输入圆的半径 例: 10");
s = sc.nextLine().trim();
CalculateUtils.calculateRoundness(s);
break;
case 4:
System.out.println("请输入椭圆的半径 例: 10 20");
s = sc.nextLine().trim();
CalculateUtils.calculateEllipse(s);
break;
case 5:
System.out.println("请输入三角形的三边 例: 10 20 30");
s = sc.nextLine().trim();
CalculateUtils.calculateTrilateral(s);
break;
case 6:
CalculateUtils.list.stream()
.sorted((o1, o2) -> (int) (o2.getPerimeter() - o1.getPerimeter()))
.forEach(System.out::println);
break;
case 7:
CalculateUtils.list.stream()
.sorted(Comparator.comparingDouble(IShape::getArea))
.forEach(System.out::println);
break;
case 8:
Collections.shuffle(CalculateUtils.list);
CalculateUtils.list.forEach(System.out::println);
break;
case 9:
CalculateUtils.list.stream()
.sorted(Comparator.comparingInt(IShape::getSign))
.forEach(System.out::println);
break;
case 10:
CalculateUtils.list.clear();
break;
default:
break;
}
}
public static void printMenu() {
System.out.println("---------菜单---------");
System.out.println("1.长方形");
System.out.println("2.正方形");
System.out.println("3.圆");
System.out.println("4.椭圆");
System.out.println("5.三角形");
System.out.println("6.按周长从大到小排序输出图形");
System.out.println("7.按面积从小到大排序输出图形");
System.out.println("8.随机输出所有图形");
System.out.println("9.查看所有图形");
System.out.println("10.删除图形");
System.out.println("0.推出程序");
System.out.println("---------------------");
}
}