软件构造blog2--基于类继承和多态的Shapes程序及GUI

(一)前言

在这里插入图片描述
在这里插入图片描述
在软件构造课上学习到上面两页ppt的时候,我有一个大胆的想法。
据我们所知,对于正方形和长方形来讲,两者有明显的继承关系,在代码实现方面会简便的很多。那么如果对更多的图形呢,况且老师上习题课已经讲过GUI,我联想起了之前看到过的一个空缺shapes类,这次我把它的代码补齐。

(二)类设计

其实对于刚刚学习java或者oop的小白,怎么去理解抽象类呢。不讲那些难懂的定义,我的理解是,就像你们班级内的人,虽然属性各不相同,但是你们班级是一样的。
在这里插入图片描述

那么我们就先写一个抽象类。

package shapes;

import java.awt.Graphics;

public abstract class Shape {
	
	public abstract void draw(Graphics g);
	public abstract int calc(Graphics g);//计算周长的虚方法
	public abstract int cals(Graphics g);//计算面积的虚方法
	
}

draw是我一会要用来画图的方法,另外两个一个求周长,一个求面积。如果你对类的继承和多态很熟悉的话,override这两个方法这部分代码会非常地容易。

(1) Circle 圆

古人就讲圆滑,做人做事儿不能太有棱角,适当的时候,圆可以让你滚的更远。实际上大家都会觉得圆这种图形最简单,就用一个半径就可以描述。但是,不要忘了,影响他位置的还有圆心坐标。

package shapes;

import java.awt.Graphics;

public class Circle extends Shape {
	private int x;
	private int y;
	private int radius;
	
	public Circle(int x, int y, int radius)
	{
		this.x = x;
		this.y = y;
		this.radius = radius;
	}
	@Override
	public void draw(Graphics g) {
		g.drawOval(x-radius, y-radius, radius*2, radius*2);
	}
	@Override
	public int calc(Graphics g) {
		return (int) (Math.PI*radius*2);//求周长,c=2*π*r
	}
	@Override
	public int cals(Graphics g) {
		return (int) (Math.PI*radius*radius);//求面积,s=π*r*r;
	}
}

(2) Ellipse

细心的读者们发现了为啥就这个类没标记中文名?在大学生涯中,英语是很重要的,不然软件构造的ppt有可能看不懂。
椭圆,四个元素,实际上每种图形需要几个元素,你可以通过查阅draw的API来判断,当时我就是看到drawoval内有四个参数,才反应过来应该是四个元素。

package shapes;

import java.awt.Graphics;

public class Ellipse extends Shape {

	private int x;
	private int y;
	private int longaxis;
	private int shortaxis;
	public Ellipse(int x, int y, int longaxis,int shortaxis)
	{
		this.x = x;
		this.y = y;
		this.longaxis = longaxis;
		this.shortaxis=shortaxis;
	}
	@Override
	public void draw(Graphics g) {
		g.drawOval(x, y, longaxis, shortaxis);
	}
	@Override
	public int calc(Graphics g) {
		return (int) (Math.PI*2*shortaxis+4*(longaxis-shortaxis));//求周长,周长公式是google的不知道对不对
	}
	@Override
	public int cals(Graphics g) {
		return (int) (Math.PI*longaxis*shortaxis);//求面积,s=π*a*b
	}

}

(3) Line 直线

毫无疑问,起点终点的横纵坐标作为参数。

package shapes;

import java.awt.Graphics;

public class Line extends Shape {
	private int x1;
	private int y1;
	private int x2;
	private int y2;
	
	public Line(int x1, int y1, int x2, int y2)
	{
		this.x1 = x1; this.y1 = y1;
		this.x2 = x2; this.y2 = y2;
	}
	
	@Override
	public void draw(Graphics g) {
		g.drawLine(x1, y1, x2, y2);
	}

	@Override
	public int calc(Graphics g) {
		int x=x2-x1;
		int y=y2-y1;
		return (int) Math.sqrt(x^2+y^2);//求周长,勾股定理
		
	}

	@Override
	public int cals(Graphics g) {//求面积,没有面积
		return 0;
	}
}

(4) Rectangle 矩形

drawRect有xy长宽四个元素,xy具体坐标表示哪个点我有点忘了,应该是中心点。

package shapes;

import java.awt.Graphics;

public class Line extends Shape {
	private int x1;
	private int y1;
	private int x2;
	private int y2;
	
	public Line(int x1, int y1, int x2, int y2)
	{
		this.x1 = x1; this.y1 = y1;
		this.x2 = x2; this.y2 = y2;
	}
	
	@Override
	public void draw(Graphics g) {
		g.drawLine(x1, y1, x2, y2);
	}

	@Override
	public int calc(Graphics g) {
		int x=x2-x1;
		int y=y2-y1;
		return (int) Math.sqrt(x^2+y^2);//求周长,勾股定理
		
	}

	@Override
	public int cals(Graphics g) {//求面积,没有面积
		return 0;
	}
}

(5) Triangle 三角形

三个点的坐标,也就是六个元素,但是求周长和面积累死我了,有更好的算法请私信我呜呜呜。

package shapes;

import java.awt.Graphics;

public class Triangle extends Shape {
	private int[] x = new int[3];
	private int[] y = new int[3];
	
	public Triangle(int x1, int y1, int x2, int y2, int x3, int y3)
	{
		x[0] = x1; x[1] = x2; x[2] = x3;
		y[0] = y1; y[1] = y2; y[2] = y3;
	}
	
	@Override
	public void draw(Graphics g) {
		g.drawPolygon(x, y, x.length);
	}

	@Override
	public int calc(Graphics g) {
		return (int) (Math.sqrt((x[0]-x[1])^2+(y[0]-y[1])^2)+Math.sqrt((x[2]-x[1])^2+(y[2]-y[1])^2)+Math.sqrt((x[0]-x[2])^2+(y[0]-y[2])^2));//求周长,此为三角形关于三边坐标的周长公式
	}

	@Override
	public int cals(Graphics g) {
		return Math.abs(x[0]*y[1]+x[1]*y[2]+x[2]*y[0]-x[0]*y[2]-x[1]*y[0]-x[2]*y[1]);//求面积,Google的三角形三边坐标的面积
	}

}

(6) Square 正方形

Square理所应当的继承了矩形的优良品质,而且周长面积公式都很清晰。

package shapes;

import java.awt.Graphics;

public class Square extends Shape 
{
	private int x;
	private int y;
	private int len;
	public Square(int x,int y,int len)
	{
		this.x=x;
		this.y=y;
		this.len=len;
	}
	@Override
	public void draw(Graphics g) {
		g.drawRect(x, y, len, len);
	}
	@Override
	public int calc(Graphics g) {//求周长,周长等于4*边长
		return 4*len;
	}
	@Override
	public int cals(Graphics g) {//求面积,面积等于边长的平方
		return len^2;
	}

}

(7) Picture 图类

picture类中我写了add,draw等实现方法,要把图形画出来。不多说,大家自己体会。

package shapes;

import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Picture extends JFrame {
	private static final long serialVersionUID = 1L;
	private int width;
	private int height;
	
	private ArrayList<Shape> listShape = new ArrayList<Shape>();
	
	private class ShapesPanel extends JPanel {
		private static final long serialVersionUID = 1L;

		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			for ( Shape s : listShape )
			{
				s.draw(g);
			}			
		}
		
	}
	
	public void add(Shape s)
	{
		listShape.add(s);
	}

	public Picture(int width, int height)
	{
		add(new ShapesPanel());
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.width = width;
		this.height = height;
	}
	
	public void draw()
	{
		setLocationRelativeTo(null);
		setSize(width, height);
		setVisible(true);
	}
}

(8) Mypic 主函数

最后弄一个main类,尝试在一个图里画出很多图形。

package shapes;

public class MyPic {
	public static void main(String[] args) 
	{
		Picture pic = new Picture(420,300);
		Circle c1 = new Circle(320,40,80);
		Rectangle r1 = new Rectangle(100, 100, 100,100);
		Triangle t1 = new Triangle(100, 100, 200, 100, 150, 50);
		Line l1 = new Line(0,205,400,205);
		Circle c2 = new Circle(200,200,50);
		Square s1 =new Square(0,0,100);
		Ellipse e1=new Ellipse(0,0,100,50);
		pic.add(c1);
		pic.add(r1);
		pic.add(t1);
		pic.add(l1);
		pic.add(c2);
		pic.add(s1);
		pic.add(e1);
		pic.draw();	
		System.out.println(c1.calc(null));//输出c1周长
		System.out.println(r1.calc(null));//输出r1周长
		System.out.println(t1.calc(null));//输出t1周长
		System.out.println(l1.calc(null));//输出l1周长
		System.out.println(c2.calc(null));//输出c2周长
		System.out.println(s1.calc(null));//输出s1周长
		System.out.println(e1.calc(null));//输出e1周长
		
		System.out.println(c1.cals(null));//输出c1面积
		System.out.println(r1.cals(null));//输出r1面积
		System.out.println(t1.cals(null));//输出t1面积
		System.out.println(l1.cals(null));//输出l1面积
		System.out.println(c2.cals(null));//输出c2面积
		System.out.println(s1.cals(null));//输出s1面积
		System.out.println(e1.cals(null));//输出e1面积
	}
}

(三)结果

在这里插入图片描述
咱也实在没啥艺术细菌,本来想画个小房子的,结果烟囱和太阳画成这个鬼样子,唉。
在这里插入图片描述

(四)总结

其实思路很简单,在做完lab123之后再看这个,简直没什么动脑的地方,可能就是在复写周长和面积的时候复杂一点。
不过还是发扬光大了类继承和多态的思想,很好的小练习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HKU Ljy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值