java 4-抽象类

题目

  1. 抽象类Shape与泛型数组列表
    1. 编写一抽象类(Shape),有一个PI属性(final static)用于存放圆周率、用于求周长的抽象方法public double getPerimeter();和用于求面积的抽象方法public double getArea();。
    2. 长方形类、三角形类与圆形类均为其子类,并各有各的属性,并均有获得其周长、面积的方法。还需要生成相应的setter/getter方法。
    3. 在一测试类中,分别建立若干个子对象(对象类型自定,尽量用到所定义的类),并放入数组或者ArrayList中,然后将各种形状的对象的所有面积与长度累加输出。
    4. 针对上面的各子类编写相应的equals,hashCode,toString(可自动生成,但需看懂代码,注意里面对double类型属性是如何进行比较的)。
      注意:所有的代码都应该放在合适的包中(包名自定)。
      思考:为什么PI属性要使用final进行修饰?
  2. Staff, Teacher, SecurityGuard, Dean
    1. 定义Staff类(职工),添加如下属性(name, address, age, sex, salary, dateHired),类型自定,其中salary为工资,dateHired为雇佣日期(java.util.Date或java.time.LocalDateTime类型)。生成相应的setter/getter方法。
    2. 编写Teacher类(教师),继承自Staff类,包含属性:department(系), speciality(专业), postAllowance(岗位津贴)。
    3. 编写SecurityGuard类(保安),继承自Staff类,包含属性:skills(专技), dangerousAllowance(高危津贴)。
    4. 编写Teacher的一个子类Dean(院长),包含属性:adminAward(行政奖金)。
    5. 定义上述各类的getter/setter方法,并添加合适的构造方法。
    6. 编写一个测试类,在测试类中添加若干个Staff, Teacher, SecurityGuard, Dean实例(个数及内容自定),并在测试类中定义并测试如下方法。
      ①编写一个方法private static void printName(Staff[] persons)打印出每个人的名字;
      ②编写一个方法private static void printSalary(Staff[] staffs)打印出Staff类或者其子类对象的薪水(注意:Staff的薪水只有salary,Teacher的薪水为salary+postAllowance,SecurityGuard的薪水为salary+dangerousAllowance,而Dean的薪水则为salary+postAllowance+adminAward);
      ③编写一方法private static void sortBySalary(Staff[] staffs),支持对Staff类及其子类按照各自的薪水降序排序;
      ④编写一方法private static void sortByAge(Staff[] staffs),对Staff对象按照年龄升序排序,再编写一个方法按name升序进行排序;
      ⑤(选做)编写一方法sortByDateHired,支持对Staff类及其子类按照各自的dateHired升序排序,可以使用java.util.Date类的getTime方法或者java.time.LocalDateTime的compareTo方法。
      
    说明:排序暂时不要使用比较器(Comparable、Comparator等)!
  3. Account, CheckingAccount, SavingAccount
    1. 定义Account类,模拟一个银行帐户,包括帐户名、余额、年利率、开户日期等成员。同时Account类拥有存款(deposit)和取款(withdraw)两个方法,方法参数及返回值自定,但要综合考虑后续测试类中的调用规范。
    2. 创建Account类的两个子类:支票帐户(CheckingAccount)、储蓄帐户(SavingAccount)。其中支票帐户有一个透支限定额,但储蓄帐户不能透支。
    3. 编写测试程序,创建若干Account、CheckingAccount、SavingAccount,打印帐号信息,同时测试存款、取款方法。
      提示:这里要注意“取款”方法的设计,在逻辑上,支票帐户允许一定额度的透支,而普通帐户和储蓄帐户不能透支。可以合理使用覆盖设计该方法。
  4. Rect, PlainRect
    1. 定义一个矩形类Rect,包含两个protected属性:矩形的宽width和高height。一个带有两个参数的构造方法,用于将width和height属性初始化。一个不带参数的构造方法,将矩形的宽和高都初始化为10。还有两个普通方法:求矩形面积的方法getArea()和求矩形周长的方法getPerimeter()。
    2. 继承Rect类编写一个具有确定位置的矩形类PlainRect,其位置用矩形的左上角坐标来标识,有两个属性:矩形左上角坐标startX和startY。两个构造方法:一个是带4个参数的构造方法,用于对startX、startY、width和height属性初始化。一个是不带参数的构造方法,将矩形初始化为左上角坐标、长和宽都为0的矩形。
    3. 为PlainRect类添加一个方法:public boolean isInside(double x, double y),用于判断某个点(x,y)是否在矩形内部。若点在矩形内,则返回true, 否则,返回false。
    4. 编写测试类,测试上述功能。
      思考:考虑如果三角形、圆形都需要添加isInside方法,你会怎么扩展代码,以达到代码重用的目的(当然也要符合类本身的设计准则及封装性原则)?
  5. 枚举类型
    • 编写枚举类型City,表示城市,定义若干常量(如厦门、北京、上海等),每个City常量都包含一个中文的描述信息(即需要一个带一个参数的构造方法)。
    • 编写枚举类型University,表示大学,定义若干常量(如集美大学、厦门大学、清华大学等,允许自定义,不限),每个University常量包含两个信息:中文描述及所在的城市(City类型)。
    • 编写简单的测试类,使用上述枚举类型赋值及输出。

实验报告

一、目的

  1. 熟悉类的继承;

  2. 掌握多态性编程;

  3. 了解反射机制。

二、实验内容与设计思想

设计思路

(1) 抽象类Shape与泛型数组列表

(2) Staff, Teacher, SecurityGuard, Dean

(3) Account, CheckingAccount, SavingAccount

(4) Rect, PlainRect

(5) 枚举类型

主要数据结构
问题1
abstract public class Shape {
    public final static double PI = 3.1415926;
    public abstract double getPerimeter();
    public abstract double getArea();}
形状类: 存放PI求周长和求面积的方法
public class Rectangle extends Shape {
private double }
长方形类: 存放长方形的长和宽
public class Circle extends Shape{
private double r;}
圆类: 存放圆的半径
public class Triangle extends Shape {
private double a,b,c;}
三角形类: 存放三角形的三条边的周长 问题二
public class Staff {
protected String name, address, sex;
protected int age;
protected double salary;
protected LocalDate dataHired;}
职工类: 存放职工的姓名,地址,性别,年龄,工资,入职日期信息。
public class Teacher extends Staff{
protected String department;
protected String speciality;
protected double postAllowance;}
教师类: 存放教师除了职工信息外的系,专业,岗位津贴信息。
public class SecurityGuard extends Staff {
private String skills;
private double dangerousAllowance;}
保安类: 存放保安除了职工信息外的专技和高危津贴信息。
public class Dean extends Teacher{
private double adminAward;}
院长类: 存放院长除了教师信息外的行政补贴 问题三
public class Account {
    protected String name;
    protected double balance, rate;
    protected LocalDate data;}
账户类: 存放账户的名字,余额,年利率,存款日期等信息
public class CheckingAccount extends Account{
private double overdraftLimit;}
支票账户类: 存放除了账户以外的透支额度信息
public class SavingAccount extends Account {}
储蓄账户类 问题四
public class Rect {
    protected double }
长方形类: 存放长方形的长和宽信息
public class PlainRect extends Rect{
    private double startX,startY;}
绝对位置长方形类: 存放长方形开始位置等信息 问题五
public enum City {
    private String chinese;}
城市枚举类
public enum University {
    private String desc;
    private City city;}
大学枚举类
主要代码结构

三、实验使用环境

软件:java version “18.0.2”,EclipseIDE 2022-06

平台:win10

四、实验步骤和调试过程

抽象类Shape与泛型数组列表

需求

  1. 编写一抽象类(Shape),有一个PI属性(final
    static)用于存放圆周率、用于求周长的抽象方法public double
    getPerimeter();和用于求面积的抽象方法public double getArea();。

  2. 长方形类、三角形类与圆形类均为其子类,并各有各的属性,并均有获得其周长、面积的方法。还需要生成相应的setter/getter方法。

  3. 在一测试类中,分别建立若干个子对象(对象类型自定,尽量用到所定义的类),并放入数组或者ArrayList中,然后将各种形状的对象的所有面积与长度累加输出。

  4. 针对上面的各子类编写相应的equals,hashCode,toString(可自动生成,但需看懂代码,注意里面对double类型属性是如何进行比较的)。

实验步骤

package exp1;

abstract public class Shape {
    public final static double PI = 3.1415926;
    public abstract double  getPerimeter();
    public abstract double getArea();
}
package exp1;

import java.util.Objects;

import static java.lang.Math.random;

public class Circle extends Shape
{
    private double r;

    public Circle()
    {
        r = random();
    }

    public Circle(double r)
    {
        this.r = r;
    }

    public double getPerimeter()
    {
        return 2 * Math.PI * r;
    }

    public double getArea()
    {
        return Math.PI * r * r;
    }

    public double getR()
    {
        return r;
    }

    public void setR(double r)
    {
        this.r = r;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Circle circle = (Circle) o;
        return Double.compare(circle.r, r) == 0;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(r);
    }

    @Override
    public String toString()
    {
        return "Circle{" +
                "r=" + r +
                '}';
    }
}
package exp1;

import java.util.Objects;

import static java.lang.Math.random;

public class Rectangle extends Shape
{
    private double width, height;

    public Rectangle()
    {
        width = random();
        height = random();
    }

    public Rectangle(double a, double b)
    {
        width = a;
        height = b;
    }

    public double getPerimeter()
    {
        return 2 * (width + height);
    }

    public double getArea()
    {
        return width * height;
    }


    public double getWidth()
    {
        return width;
    }

    public double getHeight()
    {
        return height;
    }

    public void setWidth(double width)
    {
        this.width = width;
    }

    public void setHeight(double height)
    {
        this.height = height;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Rectangle rectangle = (Rectangle) o;
        return Double.compare(rectangle.width, width) == 0 && Double.compare(rectangle.height, height) == 0;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(width, height);
    }

    @Override
    public String toString()
    {
        return "Rectangle{" +
                "width=" + width +
                ", height=" + height +
                '}';
    }
}
package exp1;

import java.util.Objects;

import static java.lang.Math.random;
import static java.lang.Math.sqrt;

public class Triangle extends Shape
{
    private double a, b, c;

    public Triangle()
    {
        a = random();
        b = random();
        c = random();
    }

    public Triangle(double a, double b, double c)
    {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public double getPerimeter()
    {
        return a + b + c;
    }

    public double getArea()
    {
        double p = (a + b + c) / 2;
        if (a + b <= c || a - b >= c)
            return 0;
        return sqrt(p * (p - a) * (p - b) * (p - c));
    }

    public double getA()
    {
        return a;
    }

    public double getB()
    {
        return b;
    }

    public double getC()
    {
        return c;
    }

    public void setA(double a)
    {
        this.a = a;
    }

    public void setB(double b)
    {
        this.b = b;
    }

    public void setC(double c)
    {
        this.c = c;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Triangle triangle = (Triangle) o;
        return Double.compare(triangle.a, a) == 0 && Double.compare(triangle.b, b) == 0 && Double.compare(triangle.c, c) == 0;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(a, b, c);
    }

    @Override
    public String toString()
    {
        return "Triangle{" +
                "a=" + a +
                ", b=" + b +
                ", c=" + c +
                '}';
    }
}
package exp1;

import java.util.ArrayList;

public class Test
{
    public static void main(String[] args) {
        System.out.println("测试内容:2个三角形,2个圆形,2个长方形的周长和与面积和");

        ArrayList<Shape> ShapeList = new ArrayList<>();
        ShapeList.add(new Rectangle());
        ShapeList.add(new Rectangle());
        ShapeList.add(new Triangle());
        ShapeList.add(new Triangle());
        ShapeList.add(new Circle());
        ShapeList.add(new Circle());

        double c = 0,s=0;
        for(Shape shape:ShapeList)
        {
            System.out.println(shape.toString());
            c+=shape.getPerimeter();
            s+=shape.getArea();
        }

        System.out.printf("所有周长和 = %.3f\n", c);
        System.out.printf("所有面积和 = %.3f\n", s);
    }
}

测试结果

**思考**

为什么PI属性要使用final进行修饰?

final作用于类的成员变量时,成员变量进行初始化赋值后,就不能再被赋值了。因为PI的值是固定的,即3.1415926,用于计算圆的面积与周长,为了保证计算结果的准确性,需要赋予PI不能被修改的属性,保证圆的面积和周长计算的正确性。

Staff, Teacher, SecurityGuard, Dean

需求

(1) 定义Staff类(职工),添加如下属性(name, address, age, sex, salary,
dateHired),类型自定,其中salary为工资,dateHired为雇佣日期(java.util.Date或java.time.LocalDateTime类型)。生成相应的setter/getter方法。

(2) 编写Teacher类(教师),继承自Staff类,包含属性:department(系),
speciality(专业), postAllowance(岗位津贴)。

(3) 编写SecurityGuard类(保安),继承自Staff类,包含属性:skills(专技),
dangerousAllowance(高危津贴)。

(4) 编写Teacher的一个子类Dean(院长),包含属性:adminAward(行政奖金)。

(5) 定义上述各类的getter/setter方法,并添加合适的构造方法。

(6) 编写一个测试类,在测试类中添加若干个Staff, Teacher, SecurityGuard,
Dean实例,并在测试类中定义并测试如下方法:

```
①编写一个方法private static void printName(Staff[] persons)打印出每个人的名字;
②编写一个方法private static void printSalary(Staff[] staffs)打印出Staff类或者其子类对象的薪水
③编写一方法private static void sortBySalary(Staff[] staffs),支持对Staff类及其子类按照各自的薪水降序排序;
④编写一方法private static void sortByAge(Staff[] staffs),对Staff对象按照年龄升序排序,再编写一个方法按name升序进行排序;
⑤(选做)编写一方法sortByDateHired,支持对Staff类及其子类按照各自的dateHired升序排序,可以使用java.util.Date类的getTime方法或者java.time.LocalDateTime的compareTo方法。
``````

实验步骤

package exp2;


import java.time.LocalDate;


public class Staff
{
    protected String name, address, sex;
    protected int age;
    protected double salary;
    protected LocalDate dataHired;

    public Staff(String name, String address, String sex, int age, double salary, LocalDate dataHired)
    {
        this.name = name;
        this.address = address;
        this.sex = sex;
        this.age = age;
        this.salary = salary;
        this.dataHired = dataHired;
    }


    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getAddress()
    {
        return address;
    }

    public void setAddress(String address)
    {
        this.address = address;
    }

    public String getSex()
    {
        return sex;
    }

    public void setSex(String sex)
    {
        this.sex = sex;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public double getSalary()
    {
        return salary;
    }

    public void setSalary(double salary)
    {
        this.salary = salary;
    }

    public LocalDate getDataHired()
    {
        return dataHired;
    }

    public void setDataHired(LocalDate dataHired)
    {
        this.dataHired = dataHired;
    }

    public double getSumSalary()
    {
        return salary;
    }
    @Override
    public String toString()
    {
        return "Staff{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", dataHired=" + dataHired +
                '}';
    }
}
package exp2;

import java.time.LocalDate;

public class Teacher extends Staff
{
    private String department;
    private String speciality;
    protected double postAllowance;

    public Teacher(String name, String address, String sex, int age, double salary, LocalDate dataHired, String department, String speciality, double postAllowance)
    {
        super(name, address, sex, age, salary, dataHired);
        this.department = department;
        this.speciality = speciality;
        this.postAllowance = postAllowance;
    }

    public String getDepartment()
    {
        return department;
    }

    public void setDepartment(String department)
    {
        this.department = department;
    }

    public String getSpeciality()
    {
        return speciality;
    }

    public void setSpeciality(String speciality)
    {
        this.speciality = speciality;
    }

    public double getPostAllowance()
    {
        return postAllowance;
    }

    public void setPostAllowance(double postAllowance)
    {
        this.postAllowance = postAllowance;
    }

    public double getSumSalary(){return super.getSumSalary()+postAllowance;}
    @Override
    public String toString()
    {
        return "Teacher{" +
                "department='" + department + '\'' +
                ", speciality='" + speciality + '\'' +
                ", postAllowance=" + postAllowance +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", dataHired=" + dataHired +
                '}';
    }
}
package exp2;

import java.time.LocalDate;

public class SecurityGuard extends Staff
{
    private String skills;
    private double dangerousAllowance;

    public SecurityGuard(String name, String address, String sex, int age, double salary, LocalDate dataHired, String skills, double dangerousAllowance)
    {
        super(name, address, sex, age, salary, dataHired);
        this.skills = skills;
        this.dangerousAllowance = dangerousAllowance;
    }

    public String getSkills()
    {
        return skills;
    }

    public void setSkills(String skills)
    {
        this.skills = skills;
    }

    public double getDangerousAllowance()
    {
        return dangerousAllowance;
    }

    public void setDangerousAllowance(double dangerousAllowance)
    {
        this.dangerousAllowance = dangerousAllowance;
    }

    public double getSumSalary(){return super.getSumSalary()+getDangerousAllowance();}

    @Override
    public String toString()
    {
        return "SecurityGuard{" +
                "skills='" + skills + '\'' +
                ", dangerousAllowance=" + dangerousAllowance +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", dataHired=" + dataHired +
                '}';
    }
}
package exp2;

import java.time.LocalDate;

public class Dean extends Teacher
{
    private double adminAward;

    public Dean(String name, String address, String sex, int age, double salary, LocalDate dataHired, String department, String speciality, double postAllowance, double adminAward)
    {
        super(name, address, sex, age, salary, dataHired, department, speciality, postAllowance);
        this.adminAward = adminAward;
    }

    public double getAdminAward()
    {
        return adminAward;
    }

    public void setAdminAward(double adminAward)
    {
        this.adminAward = adminAward;
    }

    public double getSumSalary(){return super.getSumSalary()+adminAward;}
    @Override
    public String toString()
    {
        return "Dean{" +
                "adminAward=" + adminAward +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", dataHired=" + dataHired +
                '}';
    }
}
package exp2;

import java.time.LocalDate;
import java.util.HashMap;

import static java.lang.Math.random;

public class Test
{
    static private int personNum = 4 * 3;
    private static int id;
    static private String[] departments;
    static private HashMap<String, String[]> specialists;
    static private String[] skills;


    static void init()
    {
        id = 0;
        departments = new String[]{"中文系", "美术系", "音乐系", "计算机系"};
        specialists = new HashMap<>();
        specialists.put("中文系", new String[]{"汉语言文学", "汉语言", "秘书学"});
        specialists.put("美术系", new String[]{"美术教育", "书法", "雕塑", "美术"});
        specialists.put("音乐系", new String[]{"作曲系", "声乐系", "民声系", "钢琴系", "电子琴系"});
        specialists.put("计算机系", new String[]{"软件工程", "网络工程", "计算机与科学", "智能科学与技术"});
        skills = new String[]{"抓小偷", "使用防暴叉", "看门", "查看健康码", "巡逻校园", "保卫校园"};
    }


    static String getName()
    {
        return "张三" + (++id);
    }

    static String getAddress()
    {
        return "翻斗大街翻斗花园二号楼10" + id;
    }

    static String getSex()
    {
        return random() <= 0.5 ? "男" : "女";
    }

    static int getAge()
    {
        return (int) (random() * 100);
    }

    static double getSalary()
    {
        return random() * 10000;
    }

    static LocalDate getData()
    {
        int year = 2000 + (int) (random() * 22);
        int month = 1 + (int) (random() * 11);
        int day = 1 + (int) (random() * 27);
        return LocalDate.of(year, month, day);
    }

    static double getPostAllowance()
    {
        return random() * 1000;
    }

    static String getDepartment()
    {
        return departments[(int) (random() * departments.length)];
    }

    static String getSpeciality(String department)
    {
        String[] speciality = specialists.get(department);
        return speciality[(int) (random() * speciality.length)];
    }

    static String getSkill()
    {
        return skills[(int) (random() * skills.length)];
    }

    static double getDangerousAllowance()
    {
        return random() * 1000;
    }

    static double getAdminAward()
    {
        return random() * 1000;
    }


    public static void main(String[] args)
    {
        init();
        Staff[] staffs = new Staff[personNum];

        for (int i = 0; i < personNum; i += 4)
        {
            Staff staff = new Staff(getName(), getAddress(), getSex(), getAge(), getSalary(), getData());
            String department = getDepartment();
            Teacher teacher = new Teacher(getName(), getAddress(), getSex(), getAge(), getSalary(), getData(), department, getSpeciality(department), getPostAllowance());
            SecurityGuard securityGuard = new SecurityGuard(getName(), getAddress(), getSex(), getAge(), getSalary(), getData(), getSkill(), getDangerousAllowance());
            Dean dean = new Dean(getName(), getAddress(), getSex(), getAge(), getSalary(), getData(), department, getSpeciality(department), getPostAllowance(), getAdminAward());

            staffs[i] = staff;
            staffs[i + 1] = teacher;
            staffs[i + 2] = securityGuard;
            staffs[i + 3] = dean;
        }

        System.out.println("打印名字-------------------------------------------- ");
        printName(staffs);
        System.out.println("打印薪水-------------------------------------------- ");
        printSalary(staffs);


        System.out.println("按照工资排序-------------------------------------------- ");
        sortBySalary(staffs);
        print(staffs);
        System.out.println("按照年龄排序-------------------------------------------- ");
        sortByAge(staffs);
        print(staffs);
        System.out.println("按照名字排序-------------------------------------------- ");
        sortByName(staffs);
        print(staffs);
        System.out.println("按照日期排序-------------------------------------------- ");
        sortByDateHired(staffs);
        print(staffs);
    }

    public static void printName(Staff[] persons)
    {
        for (Staff staff : persons)
            System.out.println(staff.getName());
    }

    public static void printSalary(Staff[] staffs)
    {
        for (Staff staff : staffs)
            System.out.println(staff.getSumSalary());
    }

    //薪水降序
    public static void sortBySalary(Staff[] staffs)
    {
        double[] salary = new double[staffs.length];
        for (int i = 0; i < staffs.length; i++)
        {
            Staff staff = staffs[i];
            if (staff instanceof Dean)
                salary[i] = staff.getSalary() + getPostAllowance() + getAdminAward();
            else if (staff instanceof Teacher)
                salary[i] = staff.getSalary() + ((Teacher) staff).getPostAllowance();
            else if (staff instanceof SecurityGuard)
                salary[i] = staff.getSalary() + ((SecurityGuard) staff).getDangerousAllowance();
            else
                salary[i] = staff.getSalary();
        }

        for (int i = 0; i < salary.length; i++)
        {
            double maxSalary = salary[i];
            int maxIndex = i;
            for (int j = i + 1; j < salary.length; j++)
            {
                if (salary[j] > maxSalary)
                {
                    maxSalary = salary[j];
                    maxIndex = j;
                }
            }
            Staff temp = staffs[i];
            staffs[i] = staffs[maxIndex];
            staffs[maxIndex] = temp;

            salary[maxIndex] = salary[i];
            salary[i] = maxSalary;
        }
    }

    public static void sortByAge(Staff[] staffs)
    {
        for (int i = 0; i < staffs.length; i++)
        {
            double minAge = staffs[i].getAge();
            int minIndex = i;
            for (int j = i + 1; j < staffs.length; j++)
            {
                if (staffs[j].getAge() < minAge)
                {
                    minAge = staffs[j].getSalary();
                    minIndex = j;
                }
            }
            Staff temp = staffs[i];
            staffs[i] = staffs[minIndex];
            staffs[minIndex] = temp;
        }
    }

    public static void sortByName(Staff[] staffs)
    {
        for (int i = 0; i < staffs.length; i++)
        {
            String minName = staffs[i].getName();
            int minIndex = i;
            for (int j = i + 1; j < staffs.length; j++)
            {
                if (staffs[j].getName().compareTo(minName) < 0)
                {
                    minName = staffs[j].getName();
                    minIndex = j;
                }
            }
            Staff temp = staffs[i];
            staffs[i] = staffs[minIndex];
            staffs[minIndex] = temp;
        }
    }

    public static void sortByDateHired(Staff[] staffs)
    {
        for (int i = 0; i < staffs.length; i++)
        {
            LocalDate minData = staffs[i].getDataHired();
            int minIndex = i;
            for (int j = i + 1; j < staffs.length; j++)
            {
                if (staffs[j].getDataHired().compareTo(minData) < 0)
                {
                    minData = staffs[j].getDataHired();
                    minIndex = j;
                }
            }
            Staff temp = staffs[i];
            staffs[i] = staffs[minIndex];
            staffs[minIndex] = temp;
        }
    }

    public static void print(Staff[] staffs)
    {
        for (Staff staff : staffs)
            System.out.println(staff.toString());
        System.out.println("\n\n");
    }
}

测试结果

打印名字-------------------------------------------- 
张三1
张三2
张三3
张三4
张三5
张三6
张三7
张三8
张三9
张三10
张三11
张三12
打印薪水-------------------------------------------- 
6633.06294531008
9428.598742718743
7448.960597028687
3038.878131003284
551.6559200676196
925.8101117719865
2348.1347053904615
4934.635172959999
3123.5976843061453
9671.746402711133
6355.996130809941
1735.9581985043847
按照工资排序-------------------------------------------- 
Teacher{department='音乐系', speciality='民声系', postAllowance=700.8845806408291, name='张三10', address='翻斗大街翻斗花园二号楼1010', sex='女', age=22, salary=8970.861822070303, dataHired=2013-09-08}
Teacher{department='美术系', speciality='雕塑', postAllowance=820.7487998417231, name='张三2', address='翻斗大街翻斗花园二号楼102', sex='女', age=2, salary=8607.84994287702, dataHired=2001-05-21}
SecurityGuard{skills='使用防暴叉', dangerousAllowance=371.6770331668047, name='张三3', address='翻斗大街翻斗花园二号楼103', sex='女', age=40, salary=7077.283563861882, dataHired=2006-01-26}
Staff{name='张三1', address='翻斗大街翻斗花园二号楼101', sex='男', age=75, salary=6633.06294531008, dataHired=2003-02-25}
SecurityGuard{skills='查看健康码', dangerousAllowance=836.0591738059112, name='张三11', address='翻斗大街翻斗花园二号楼1011', sex='男', age=1, salary=5519.93695700403, dataHired=2019-05-25}
Dean{adminAward=159.94750340247975, name='张三8', address='翻斗大街翻斗花园二号楼108', sex='男', age=90, salary=4299.213709569869, dataHired=2013-08-19}
Dean{adminAward=60.242660478721845, name='张三4', address='翻斗大街翻斗花园二号楼104', sex='女', age=4, salary=2329.668251712581, dataHired=2006-11-25}
Staff{name='张三9', address='翻斗大街翻斗花园二号楼109', sex='女', age=81, salary=3123.5976843061453, dataHired=2005-02-12}
Dean{adminAward=585.8596557078308, name='张三12', address='翻斗大街翻斗花园二号楼1012', sex='女', age=41, salary=799.5529156185355, dataHired=2004-03-07}
SecurityGuard{skills='巡逻校园', dangerousAllowance=977.9312768646712, name='张三7', address='翻斗大街翻斗花园二号楼107', sex='女', age=49, salary=1370.2034285257903, dataHired=2007-09-13}
Teacher{department='音乐系', speciality='作曲系', postAllowance=11.256572461248116, name='张三6', address='翻斗大街翻斗花园二号楼106', sex='男', age=52, salary=914.5535393107384, dataHired=2004-04-04}
Staff{name='张三5', address='翻斗大街翻斗花园二号楼105', sex='男', age=63, salary=551.6559200676196, dataHired=2016-07-10}



按照年龄排序-------------------------------------------- 
Staff{name='张三5', address='翻斗大街翻斗花园二号楼105', sex='男', age=63, salary=551.6559200676196, dataHired=2016-07-10}
Teacher{department='音乐系', speciality='民声系', postAllowance=700.8845806408291, name='张三10', address='翻斗大街翻斗花园二号楼1010', sex='女', age=22, salary=8970.861822070303, dataHired=2013-09-08}
Teacher{department='美术系', speciality='雕塑', postAllowance=820.7487998417231, name='张三2', address='翻斗大街翻斗花园二号楼102', sex='女', age=2, salary=8607.84994287702, dataHired=2001-05-21}
SecurityGuard{skills='使用防暴叉', dangerousAllowance=371.6770331668047, name='张三3', address='翻斗大街翻斗花园二号楼103', sex='女', age=40, salary=7077.283563861882, dataHired=2006-01-26}
SecurityGuard{skills='查看健康码', dangerousAllowance=836.0591738059112, name='张三11', address='翻斗大街翻斗花园二号楼1011', sex='男', age=1, salary=5519.93695700403, dataHired=2019-05-25}
Staff{name='张三1', address='翻斗大街翻斗花园二号楼101', sex='男', age=75, salary=6633.06294531008, dataHired=2003-02-25}
Dean{adminAward=60.242660478721845, name='张三4', address='翻斗大街翻斗花园二号楼104', sex='女', age=4, salary=2329.668251712581, dataHired=2006-11-25}
Dean{adminAward=159.94750340247975, name='张三8', address='翻斗大街翻斗花园二号楼108', sex='男', age=90, salary=4299.213709569869, dataHired=2013-08-19}
Dean{adminAward=585.8596557078308, name='张三12', address='翻斗大街翻斗花园二号楼1012', sex='女', age=41, salary=799.5529156185355, dataHired=2004-03-07}
SecurityGuard{skills='巡逻校园', dangerousAllowance=977.9312768646712, name='张三7', address='翻斗大街翻斗花园二号楼107', sex='女', age=49, salary=1370.2034285257903, dataHired=2007-09-13}
Teacher{department='音乐系', speciality='作曲系', postAllowance=11.256572461248116, name='张三6', address='翻斗大街翻斗花园二号楼106', sex='男', age=52, salary=914.5535393107384, dataHired=2004-04-04}
Staff{name='张三9', address='翻斗大街翻斗花园二号楼109', sex='女', age=81, salary=3123.5976843061453, dataHired=2005-02-12}



按照名字排序-------------------------------------------- 
Staff{name='张三1', address='翻斗大街翻斗花园二号楼101', sex='男', age=75, salary=6633.06294531008, dataHired=2003-02-25}
Teacher{department='音乐系', speciality='民声系', postAllowance=700.8845806408291, name='张三10', address='翻斗大街翻斗花园二号楼1010', sex='女', age=22, salary=8970.861822070303, dataHired=2013-09-08}
SecurityGuard{skills='查看健康码', dangerousAllowance=836.0591738059112, name='张三11', address='翻斗大街翻斗花园二号楼1011', sex='男', age=1, salary=5519.93695700403, dataHired=2019-05-25}
Dean{adminAward=585.8596557078308, name='张三12', address='翻斗大街翻斗花园二号楼1012', sex='女', age=41, salary=799.5529156185355, dataHired=2004-03-07}
Teacher{department='美术系', speciality='雕塑', postAllowance=820.7487998417231, name='张三2', address='翻斗大街翻斗花园二号楼102', sex='女', age=2, salary=8607.84994287702, dataHired=2001-05-21}
SecurityGuard{skills='使用防暴叉', dangerousAllowance=371.6770331668047, name='张三3', address='翻斗大街翻斗花园二号楼103', sex='女', age=40, salary=7077.283563861882, dataHired=2006-01-26}
Dean{adminAward=60.242660478721845, name='张三4', address='翻斗大街翻斗花园二号楼104', sex='女', age=4, salary=2329.668251712581, dataHired=2006-11-25}
Staff{name='张三5', address='翻斗大街翻斗花园二号楼105', sex='男', age=63, salary=551.6559200676196, dataHired=2016-07-10}
Teacher{department='音乐系', speciality='作曲系', postAllowance=11.256572461248116, name='张三6', address='翻斗大街翻斗花园二号楼106', sex='男', age=52, salary=914.5535393107384, dataHired=2004-04-04}
SecurityGuard{skills='巡逻校园', dangerousAllowance=977.9312768646712, name='张三7', address='翻斗大街翻斗花园二号楼107', sex='女', age=49, salary=1370.2034285257903, dataHired=2007-09-13}
Dean{adminAward=159.94750340247975, name='张三8', address='翻斗大街翻斗花园二号楼108', sex='男', age=90, salary=4299.213709569869, dataHired=2013-08-19}
Staff{name='张三9', address='翻斗大街翻斗花园二号楼109', sex='女', age=81, salary=3123.5976843061453, dataHired=2005-02-12}



按照日期排序-------------------------------------------- 
Teacher{department='美术系', speciality='雕塑', postAllowance=820.7487998417231, name='张三2', address='翻斗大街翻斗花园二号楼102', sex='女', age=2, salary=8607.84994287702, dataHired=2001-05-21}
Staff{name='张三1', address='翻斗大街翻斗花园二号楼101', sex='男', age=75, salary=6633.06294531008, dataHired=2003-02-25}
Dean{adminAward=585.8596557078308, name='张三12', address='翻斗大街翻斗花园二号楼1012', sex='女', age=41, salary=799.5529156185355, dataHired=2004-03-07}
Teacher{department='音乐系', speciality='作曲系', postAllowance=11.256572461248116, name='张三6', address='翻斗大街翻斗花园二号楼106', sex='男', age=52, salary=914.5535393107384, dataHired=2004-04-04}
Staff{name='张三9', address='翻斗大街翻斗花园二号楼109', sex='女', age=81, salary=3123.5976843061453, dataHired=2005-02-12}
SecurityGuard{skills='使用防暴叉', dangerousAllowance=371.6770331668047, name='张三3', address='翻斗大街翻斗花园二号楼103', sex='女', age=40, salary=7077.283563861882, dataHired=2006-01-26}
Dean{adminAward=60.242660478721845, name='张三4', address='翻斗大街翻斗花园二号楼104', sex='女', age=4, salary=2329.668251712581, dataHired=2006-11-25}
SecurityGuard{skills='巡逻校园', dangerousAllowance=977.9312768646712, name='张三7', address='翻斗大街翻斗花园二号楼107', sex='女', age=49, salary=1370.2034285257903, dataHired=2007-09-13}
Dean{adminAward=159.94750340247975, name='张三8', address='翻斗大街翻斗花园二号楼108', sex='男', age=90, salary=4299.213709569869, dataHired=2013-08-19}
Teacher{department='音乐系', speciality='民声系', postAllowance=700.8845806408291, name='张三10', address='翻斗大街翻斗花园二号楼1010', sex='女', age=22, salary=8970.861822070303, dataHired=2013-09-08}
Staff{name='张三5', address='翻斗大街翻斗花园二号楼105', sex='男', age=63, salary=551.6559200676196, dataHired=2016-07-10}
SecurityGuard{skills='查看健康码', dangerousAllowance=836.0591738059112, name='张三11', address='翻斗大街翻斗花园二号楼1011', sex='男', age=1, salary=5519.93695700403, dataHired=2019-05-25}
Account, CheckingAccount, SavingAccount

需求

  1. 定义Account类,模拟一个银行帐户,包括帐户名、余额、年利率、开户日期等成员。同时Account类拥有存款(deposit)和取款(withdraw)两个方法。
  2. 创建Account类的两个子类:支票帐户(CheckingAccount)、储蓄帐户(SavingAccount)。其中支票帐户有一个透支限定额,但储蓄帐户不能透支。
    3.编写测试程序,创建若干Account、CheckingAccount、SavingAccount,打印帐号信息,同时测试存款、取款方法。

实验步骤

package exp3;

import java.time.LocalDate;

public class Account
{
    protected String name;
    protected double balance, rate;
    protected LocalDate data;

    public Account(String name, double balance, double rate, LocalDate data)
    {
        this.name = name;
        this.balance = balance;
        this.rate = rate;
        this.data = data;
    }

    @Override
    public String toString()
    {
        return "Account{" +
                "name='" + name + '\'' +
                ", balance=" + balance +
                ", rate=" + rate +
                ", data=" + data +
                '}';
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public double getBalance()
    {
        return balance;
    }

    public void setBalance(double balance)
    {
        this.balance = balance;
    }

    public double getRate()
    {
        return rate;
    }

    public void setRate(double rate)
    {
        this.rate = rate;
    }

    public LocalDate getData()
    {
        return data;
    }

    public void setData(LocalDate data)
    {
        this.data = data;
    }

    public boolean deposit(double money)
    {
        //正常情况下,银行存款成功。
        balance += money;
        return true;
    }

    public boolean withdraw(double money)
    {
        if (balance >= money)
        {
            balance -= money;
            return true;
        }
        return false;
    }
}
package exp3;

import java.time.LocalDate;

public class CheckingAccount extends Account
{
    private double overdraftLimit;

    public CheckingAccount(String name, double balance, double rate, LocalDate data, double overdraftLimit)
    {
        super(name, balance, rate, data);
        this.overdraftLimit = overdraftLimit;
    }

    @Override
    public String toString()
    {
        return "CheckingAccount{" +
                "overdraftLimit=" + overdraftLimit +
                ", name='" + name + '\'' +
                ", balance=" + balance +
                ", rate=" + rate +
                ", data=" + data +
                '}';
    }

    public double getOverdraftLimit()
    {
        return overdraftLimit;
    }

    public void setOverdraftLimit(double overdraftLimit)
    {
        this.overdraftLimit = overdraftLimit;
    }


    public boolean withdraw(double money)
    {
        if (balance + overdraftLimit >= money)
        {
            balance -= money;
            return true;
        }
        return false;
    }
}
package exp3;

import java.time.LocalDate;

public class SavingAccount extends Account
{

    public SavingAccount(String name, double balance, double rate, LocalDate data)
    {
        super(name, balance, rate, data);
    }

    @Override
    public String toString()
    {
        return "SavingAccount{" +
                "name='" + name + '\'' +
                ", balance=" + balance +
                ", rate=" + rate +
                ", data=" + data +
                '}';
    }

}
package exp3;

import exp2.Dean;

import java.time.LocalDate;

import static java.lang.Math.random;

public class Test
{
    private static int id = 0, accountNum = 6;

    static String getName()
    {
        return "张三" + (++id);
    }

    static double getBalance()
    {
        return random() * 10000;
    }

    static double getRate()
    {
        return random() / 5;
    }

    static LocalDate getData()
    {
        int year = 2000 + (int) (random() * 22);
        int month = 1 + (int) (random() * 11);
        int day = 1 + (int) (random() * 27);
        return LocalDate.of(year, month, day);
    }

    static double getOverdraftLimit()
    {
        return random() * 1000;
    }


    public static void main(String[] args)
    {
        Account[] accounts = new Account[accountNum];

        for (int i = 0; i < accountNum; i += 3)
        {
            Account account = new Account(getName(), getBalance(), getRate(), getData());
            CheckingAccount checkingAccount = new CheckingAccount(getName(), getBalance(), getRate(), getData(), getOverdraftLimit());
            SavingAccount savingAccount = new SavingAccount(getName(), getBalance(), getRate(), getData());

            accounts[i] = account;
            accounts[i + 1] = checkingAccount;
            accounts[i + 2] = savingAccount;
        }
        testDeposit(accounts);
        testWithdraw(accounts);
    }

    static void testDeposit(Account[] accounts)
    {
        for (Account account : accounts)
        {
            System.out.println(account.toString());
            for (int i = 0; i < 3; i++)
            {
                double deposit = random() * 10000;
                boolean isDeposit = account.deposit(deposit);
                double rest = account.getBalance();
                if(isDeposit)
                    System.out.println("本次存款:" + deposit + "; 账户余额:" + rest);
                else
                    System.out.println("存款失败!!!本次存款:" + deposit + "; 账户余额:" + rest);

            }
        }
    }

    static void testWithdraw(Account[] accounts)
    {
        for (Account account : accounts)
        {
            System.out.println(account.toString());
            ;
            for (int i = 0; i < 5; i++)
            {
                double withdraw = random() * 10000;
                boolean isWithdraw = account.withdraw(withdraw);
                if (!isWithdraw)
                    System.out.println("取款失败!!!  本次取款:" + withdraw + "; 账户余额" + account.getBalance());
                else
                    System.out.println("本次取款:" + withdraw + "; 账户余额:" + account.getBalance());
            }
        }
    }

}

测试结果

Account{name='张三1', balance=933.474255433101, rate=0.15794802587665657, data=2013-09-09}
本次存款:1435.3516457224125; 账户余额:2368.8259011555137
本次存款:5314.728275595264; 账户余额:7683.5541767507775
本次存款:4914.205969747067; 账户余额:12597.760146497843
CheckingAccount{overdraftLimit=719.1432398157424, name='张三2', balance=1052.7164081592034, rate=0.019336702177354836, data=2020-10-04}
本次存款:625.7695650596728; 账户余额:1678.485973218876
本次存款:902.860486362047; 账户余额:2581.3464595809232
本次存款:310.7017017713287; 账户余额:2892.048161352252
SavingAccount{name='张三3', balance=2813.8003588990136, rate=0.0446988976866014, data=2013-08-18}
本次存款:5722.725508379995; 账户余额:8536.525867279008
本次存款:4599.225917923743; 账户余额:13135.75178520275
本次存款:4432.232340733232; 账户余额:17567.984125935982
Account{name='张三4', balance=3557.0710330355705, rate=0.005577905152081985, data=2000-04-01}
本次存款:2495.4326737061892; 账户余额:6052.50370674176
本次存款:9579.590818288312; 账户余额:15632.094525030072
本次存款:745.9618299076665; 账户余额:16378.056354937738
CheckingAccount{overdraftLimit=560.1231022723065, name='张三5', balance=8122.814286408357, rate=0.09710540846220875, data=2009-04-20}
本次存款:2815.8529204257275; 账户余额:10938.667206834085
本次存款:6466.063219038712; 账户余额:17404.730425872796
本次存款:3249.629394177388; 账户余额:20654.359820050184
SavingAccount{name='张三6', balance=7878.075914329617, rate=0.1426055747872584, data=2019-02-01}
本次存款:2201.083625876181; 账户余额:10079.159540205797
本次存款:9648.7101753008; 账户余额:19727.869715506597
本次存款:3934.6466327086005; 账户余额:23662.5163482152
Account{name='张三1', balance=12597.760146497843, rate=0.15794802587665657, data=2013-09-09}
本次取款:4015.6452408837717; 账户余额:8582.114905614071
本次取款:6628.010415309438; 账户余额:1954.1044903046331
取款失败!!!  本次取款:9193.761050746527; 账户余额1954.1044903046331
本次取款:1813.1803282152537; 账户余额:140.92416208937948
取款失败!!!  本次取款:8163.185496634372; 账户余额140.92416208937948
CheckingAccount{overdraftLimit=719.1432398157424, name='张三2', balance=2892.048161352252, rate=0.019336702177354836, data=2020-10-04}
取款失败!!!  本次取款:4996.945132412102; 账户余额2892.048161352252
本次取款:2885.466431990691; 账户余额:6.581729361560974
取款失败!!!  本次取款:1002.0008886107589; 账户余额6.581729361560974
取款失败!!!  本次取款:3928.817800902182; 账户余额6.581729361560974
取款失败!!!  本次取款:5618.867190310844; 账户余额6.581729361560974
SavingAccount{name='张三3', balance=17567.984125935982, rate=0.0446988976866014, data=2013-08-18}
本次取款:1788.6837646796528; 账户余额:15779.30036125633
本次取款:6218.762078789101; 账户余额:9560.538282467229
本次取款:7601.187850447763; 账户余额:1959.350432019466
本次取款:339.6403894646294; 账户余额:1619.7100425548367
取款失败!!!  本次取款:5777.390209518481; 账户余额1619.7100425548367
Account{name='张三4', balance=16378.056354937738, rate=0.005577905152081985, data=2000-04-01}
本次取款:4168.104135325106; 账户余额:12209.952219612633
本次取款:7567.644153506649; 账户余额:4642.308066105984
取款失败!!!  本次取款:5667.986956277919; 账户余额4642.308066105984
本次取款:1457.463374361443; 账户余额:3184.844691744541
取款失败!!!  本次取款:4627.519355052292; 账户余额3184.844691744541
CheckingAccount{overdraftLimit=560.1231022723065, name='张三5', balance=20654.359820050184, rate=0.09710540846220875, data=2009-04-20}
本次取款:15.228844789909601; 账户余额:20639.130975260276
本次取款:2792.706007480399; 账户余额:17846.424967779876
本次取款:9930.016969273096; 账户余额:7916.40799850678
本次取款:6612.797440612269; 账户余额:1303.6105578945107
本次取款:1723.3537191112248; 账户余额:-419.74316121671404
SavingAccount{name='张三6', balance=23662.5163482152, rate=0.1426055747872584, data=2019-02-01}
本次取款:6938.662705042924; 账户余额:16723.853643172275
本次取款:2376.5541381111434; 账户余额:14347.299505061132
本次取款:9686.840125935818; 账户余额:4660.459379125314
取款失败!!!  本次取款:9926.49268973857; 账户余额4660.459379125314
取款失败!!!  本次取款:8317.71159279959; 账户余额4660.459379125314
Rect, PlainRect

需求

  1. 定义一个矩形类Rect,包含两个protected属性:矩形的宽width和高height。一个带有两个参数的构造方法,用于将width和height属性初始化。一个不带参数的构造方法,将矩形的宽和高都初始化为10。还有两个普通方法:求矩形面积的方法getArea()和求矩形周长的方法getPerimeter()。

  2. 继承Rect类编写一个具有确定位置的矩形类PlainRect,其位置用矩形的左上角坐标来标识,有两个属性:矩形左上角坐标startX和startY。两个构造方法:一个是带4个参数的构造方法,用于对startX、startY、width和height属性初始化。一个是不带参数的构造方法,将矩形初始化为左上角坐标、长和宽都为0的矩形。

  3. 为PlainRect类添加一个方法:public boolean isInside(double x, double
    y),用于判断某个点(x,y)是否在矩形内部。若点在矩形内,则返回true,
    否则,返回false。

  4. 编写测试类,测试上述功能。

实验步骤

package exp4;

public class Rect
{
    protected double width, height;

    public Rect()
    {
        width = 10;
        height = 10;
    }

    public Rect(double a, double b)
    {
        width = a;
        height = b;
    }

    public double getWidth()
    {
        return width;
    }

    public void setWidth(double width)
    {
        this.width = width;
    }

    public double getHeight()
    {
        return height;
    }

    public void setHeight(double height)
    {
        this.height = height;
    }

    public double getPerimeter()
    {
        return 2 * (width + height);
    }

    public double getArea()
    {
        return width * height;
    }

    @Override
    public String toString()
    {
        return "Rect{" +
                "width=" + width +
                ", height=" + height +
                '}';
    }
}
package exp4;

public class PlainRect extends Rect
{
    private double startX, startY;

    PlainRect(double a, double b, double x, double y)
    {
        super(a, b);
        this.startX = x;
        this.startY = y;
    }

    PlainRect()
    {
        super();
        this.startX = 0;
        this.startY = 0;
    }

    public double getStartX()
    {
        return startX;
    }

    public void setStartX(double startX)
    {
        this.startX = startX;
    }

    public double getStartY()
    {
        return startY;
    }

    public void setStartY(double startY)
    {
        this.startY = startY;
    }

    public boolean isInside(double x, double y)
    {
        return startX <= x && x <= startX + width && startY <= y && y <= startY + height;
    }

    @Override
    public String toString()
    {
        return "PlainRect{" +
                "startX=" + startX +
                ", startY=" + startY +
                ", width=" + width +
                ", height=" + height +
                '}';
    }
}
package exp4;

import java.util.ArrayList;

import static java.lang.Math.random;

public class Test
{
    private static final int rectNum = 5;

    public static void main(String[] args)
    {
        ArrayList<Rect> rectangles = new ArrayList<>();
        ArrayList<Rect> plainRectangles = new ArrayList<>();


        rectangles.add(new Rect());
        plainRectangles.add(new PlainRect());

        for (int i = 0; i < rectNum; i++)
        {
            rectangles.add(new Rect(random() * 100, random() * 100));
            plainRectangles.add(new PlainRect(random() * 100, random() * 100, random() * 100, random() * 100));
            System.out.println(rectangles.get(i).toString());
            System.out.println(plainRectangles.get(i).toString());
        }


        System.out.println("\n\n测试计算面积功能-------------------------------------------- ");
        TestArea(rectangles);
        TestArea(plainRectangles);

        System.out.println("\n\n测试计算周长功能-------------------------------------------- ");
        TestPerimeter(rectangles);
        TestPerimeter(plainRectangles);

        System.out.println("\n\n测试isInside功能-------------------------------------------- ");
        TestIsInside(plainRectangles.toArray(new PlainRect[plainRectangles.size()]));
    }

    static void TestArea(ArrayList<Rect> Rects)
    {
        for (Rect rect : Rects)
        {
            System.out.println(rect.getArea());
        }
    }

    static void TestPerimeter(ArrayList<Rect> Rects)
    {
        for (Rect rect : Rects)
        {
            System.out.println(rect.getPerimeter());
        }
    }

    static void TestIsInside(PlainRect[] plainRects)
    {
        for (PlainRect plainRect : plainRects)
        {
            double x = random(), y = random();
            if (plainRect.isInside(x, y))
                System.out.printf("(%.2f,%.2f)在长方形内\n", x, y);
            else
                System.out.printf("(%.2f,%.2f)不在长方形内\n", x, y);
        }
    }
}

测试结果

Rect{width=10.0, height=10.0}
PlainRect{startX=0.0, startY=0.0, width=10.0, height=10.0}
Rect{width=35.02040089705238, height=17.280704142870785}
PlainRect{startX=12.108056784690636, startY=39.96846765918908, width=14.426734562432664, height=33.468681454708126}
Rect{width=74.95443826367449, height=67.87812473918562}
PlainRect{startX=64.81433609250183, startY=85.71121399940334, width=49.96713425339784, height=24.144264898780676}
Rect{width=9.385150804177012, height=13.344772636058966}
PlainRect{startX=45.741333267707795, startY=54.20507492746388, width=84.46581522428329, height=55.553856362342756}
Rect{width=93.76271822280935, height=57.776767525680896}
PlainRect{startX=56.09364685417282, startY=87.23305464078285, width=7.4746524638941825, height=82.54698257534056}


测试计算面积功能-------------------------------------------- 
100.0
605.1771868666889
5087.7667102172845
125.2427036368682
5417.30677333518
3623.576738297299
100.0
482.84378350168686
1206.419725646975
4692.401766498018
617.0100066937995
3415.908581705208


测试计算周长功能-------------------------------------------- 
40.0
104.60221007984634
285.66512600572025
45.45984688047196
303.0789714969805
252.97567541110539
40.0
95.79083203428158
148.222798304357
280.03934317325206
180.0432700784695
253.83790515344026


测试isInside功能-------------------------------------------- 
(0.95,0.36)在长方形内
(0.50,0.22)不在长方形内
(0.98,0.52)不在长方形内
(0.24,0.95)不在长方形内
(0.55,0.49)不在长方形内
(0.05,0.64)不在长方形内

思考

考虑如果三角形、圆形都需要添加isInside方法,你会怎么扩展代码,以达到代码重用的目的(当然也要符合类本身的设计准则及封装性原则)?

定义Shape类,isInside方法作为抽象方法,三角形,圆形和长方形继承Shape类,并且分别添加isInside方法。

枚举类型

需求

(1)编写枚举类型City,表示城市,定义若干常量(如厦门、北京、上海等),每个City常量都包含一个中文的描述信息(即需要一个带一个参数的构造方法)。

(2)编写枚举类型University,表示大学,定义若干常量(如集美大学、厦门大学、清华大学等,允许自定义,不限),每个University常量包含两个信息:中文描述及所在的城市(City类型)。

(3)编写简单的测试类,使用上述枚举类型赋值及输出。

实验步骤

package exp5;

public enum City
{
    XIAMEN("厦门"),
    BEIJING("北京"),
    SHANGHAI("上海");

    private String desc;

    public String getDesc()
    {
        return desc;
    }

    public void setDesc(String chinese)
    {
        this.desc = chinese;
    }

    City(String chinese)
    {
        this.desc = chinese;
    }
}
package exp5;

public enum University
{
    XMU("厦门大学", City.XIAMEN),
    PKU("北京大学", City.BEIJING),
    THU("清华大学", City.BEIJING),
    JMU("集美大学", City.XIAMEN),
    SHU("上海大学", City.SHANGHAI);

    private String desc;
    private City city;

    public String getDesc()
    {
        return desc;
    }

    public void setDesc(String chinese)
    {
        this.desc = chinese;
    }

    public City getCity()
    {
        return city;
    }

    public void setCity(City city)
    {
        this.city = city;
    }

    University(String chinese, City city)
    {
        this.desc = chinese;
        this.city = city;
    }
}
package exp5;

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("测试City--------------------------------------------");
        String xiaMen = City.XIAMEN.getDesc();
        String beiJing = City.BEIJING.getDesc();
        String shangHai = City.BEIJING.getDesc();

        System.out.println(xiaMen);
        System.out.println(beiJing);
        System.out.println(shangHai);

        System.out.println("测试University--------------------------------------------");
        String xiaMenU = University.XMU.getDesc();
        City XiaMen = University.XMU.getCity();
        String beiJingU = University.PKU.getDesc();
        City Beijing = University.PKU.getCity();

        System.out.println(xiaMenU + " " + XiaMen.getDesc());
        System.out.println(beiJingU + " " + Beijing.getDesc());
    }

}

测试结果

五、实验小结

实验中遇到的问题及解决过程

关于instanceof:

使用instanceof判断子类的类型,(子类类型instanceof父类类型/本身类型)是正确的,但是(父类类型
instanceof 子类类型)是错误的。

所以当存在父类,子类,子类的子类等多类型需要判断时,应当先从最深的子类开始判断,即判断子类的子类–>子类–>父类。

father var = new son();

此时仍然的属于子类son,即此时(var instanceof son)的结果是true。

关于isAssignableFrom:

使用isAssignableFrom判断两个对象所表示的类或接口是否相同。

子类对象.getClass().isAssignableFrom(父类对象.getClass())的结果是false。

父类对象.getClass().isAssignableFrom(子类对象/自身同类对象.getClass())的结果是false。

实验中产生的错误及原因分析

实验体会和收获。

通过写代码和实验报告的形式熟悉类的继承,掌握多态性编程,了解反射机制。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,类与继承-抽象类有以下几个关键点。首先,继承是指一个类可以继承自另一个类。被继承的类被称为父类/超类/基类,而继承其他类的类被称为子类。继承使得子类可以拥有父类中所有的成员(成员变量和成员方法),从而提高了代码的复用性。 其次,当子类继承自一个抽象类时,子类必须重写父类所有的抽象方法,否则该子类也必须声明为抽象类。最终,必须有子类实现该父类的抽象方法,否则从最初的父类到最终的子类都不能创建对象,失去了继承的意义。 一个示例代码如下: ``` public abstract class Animal { public abstract void run(); } public class Cat extends Animal { public void run() { System.out.println("小猫在墙头走~~~"); } } public class CatTest { public static void main(String[] args) { Cat c = new Cat(); c.run(); } } ``` 在上述代码中,Animal是一个抽象类,其中定义了一个抽象方法run。Cat类继承自Animal类,并且重写了run方法。在CatTest类的main方法中,创建了一个Cat对象并调用了run方法。 更多关于Java类与继承-抽象类的知识,可以参考Java基础教程之接口的继承与抽象类。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java面向对象基础——继承、抽象类](https://blog.csdn.net/qq_42538127/article/details/115426682)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【JavaSe】面向对象篇(六) 抽象类](https://blog.csdn.net/qq_41744145/article/details/100023046)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java基础教程之接口的继承与抽象类](https://download.csdn.net/download/weixin_38516270/12808613)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值