jmu-Java-PTA题解 (jmu-Java-03面向对象-06-继承覆盖综合练习-Person、Student、Employee、Company) 网安2312陈卓

问题要求

定义Person抽象类,Student类、Company类,Employee类。

Person类的属性:String name, int age, boolean gender
Person类的方法:

public Person(String name, int age, boolean gender);
public String toString();         //返回"name-age-gender"格式的字符串
public boolean equals(Object obj);//比较name、age、gender,都相同返回true,否则返回false

Student类继承自Person,属性:String stuNo, String clazz
Student类的方法:

//建议使用super复用Person类的相关有参构造函数
public Student(String name, int age, boolean gender, String stuNo, String clazz);
public String toString();         //返回 “Student:person的toString-stuNo-clazz”格式的字符串
public boolean equals(Object obj);//首先调用父类的equals方法,如果返回true,则继续比较stuNo与clazz。

Company类属性:String name
Company类方法:

public Company(String name);
public String toString();         //直接返回name
public boolean equals(Object obj);//name相同返回true

Employee类继承自Person,属性:Company company, double salary
Employee类方法

//建议使用super复用Person类的相关有参构造函数
public Employee(String name, int age, boolean gender, double salary, Company company);
public String toString();         //返回"Employee:person的toString-company-salary"格式的字符串
public boolean equals(Object obj);//首先调用父类的equals方法,如果返回true。再比较company与salary。
//比较salary属性时,使用DecimalFormat df = new DecimalFormat("#.#");保留1位小数

编写equals方法重要说明:

  1. 对Employee的company属性的比较。要考虑传入为null的情况。如果company不为null且传入为null,返回false
  2. 对所有String字符类型比较时,也要考虑null情况。

提示

  1. 排序可使用Collections.sort
  2. equals方法要考虑周全

main方法说明

  1. 创建若干Student对象、Employee对象。
    输入s,然后依次输入name age gender stuNo clazz创建Student对象。
    输入e,然后依次输入name age gender salary company创建Employee对象。
    然后将创建好的对象放入List personList。输入其他字符,则结束创建。
    创建说明: 对于String类型,如果为null则不创建对象,而赋值为null。对于company属性,如果为null则赋值为null,否则创建相应的Company对象。

  2. 对personList中的元素实现先按照姓名升序排序,姓名相同再按照年龄升序排序。提示:可使用Comparable或Comparator

  3. 接受输入,如果输入为exit则return退出程序,否则继续下面步骤。

  4. 将personList中的元素按照类型分别放到stuList与empList。注意:不要将两个内容相同的对象放入列表(是否相同是根据equals返回结果进行判定)。

  5. 输出字符串stuList,然后输出stuList中的每个对象。

  6. 输出字符串empList,然后输出empList中的每个对象。

1-3为一个测试点
4-6为一个测试点

输入样例:

s zhang 23 false 001 net15
e wang 18 true 3000.51 IBM
s zhang 23 false 001 net15
e bo 25 true 5000.51 IBM
e bo 25 true 5000.52 IBM
e bo 18 true 5000.54 IBM
e tan 25 true 5000.56 IBM
e tan 25 true 5000.51 IBM
s wang 17 false 002 null
s wang 17 false 002 null
e hua 16 false 1000 null
s wang 17 false 002 net16
e hua 16 false 1000 null
e hua 18 false 1234 MicroSoft
!
continue

输出样例:

Employee:bo-18-true-IBM-5000.54
Employee:bo-25-true-IBM-5000.51
Employee:bo-25-true-IBM-5000.52
Employee:hua-16-false-null-1000.0
Employee:hua-16-false-null-1000.0
Employee:hua-18-false-MicroSoft-1234.0
Employee:tan-25-true-IBM-5000.56
Employee:tan-25-true-IBM-5000.51
Student:wang-17-false-002-null
Student:wang-17-false-002-null
Student:wang-17-false-002-net16
Employee:wang-18-true-IBM-3000.51
Student:zhang-23-false-001-net15
Student:zhang-23-false-001-net15
stuList
Student:wang-17-false-002-null
Student:wang-17-false-002-net16
Student:zhang-23-false-001-net15
empList
Employee:bo-18-true-IBM-5000.54
Employee:bo-25-true-IBM-5000.51
Employee:hua-16-false-null-1000.0
Employee:hua-18-false-MicroSoft-1234.0
Employee:tan-25-true-IBM-5000.56
Employee:tan-25-true-IBM-5000.51
Employee:wang-18-true-IBM-3000.51

关键点

  • 继承与多态:通过 Person 抽象类定义统一接口,Student 和 Employee 继承并实现子类特有逻辑,父类引用(List)存储子类对象,利用多态实现统一处理.
  • equals 方法设计:父类 equals 仅比较自身属性,子类先调用父类 equals,再比较新增属性,+处理 String 和 Company 的 null 比较,避免 NullPointerException,Employee 中对 salary 保留 1 位小数后比较,确保精度一致.
  • 输入处理与空值判断:输入为 null 时,直接赋值为 null(如 clazz、company),混合使用 next() 与 nextLine() 时,注意消耗残留换行符.
  • 集合排序与去重:使用 Collections.sort 结合 Comparator 实现自定义排序,通过 List.contains() 结合 equals 方法实现对象去重.

解题步骤

第一步:定义抽象类 Person

abstract class Person {  
    String name;  
    int age;  
    boolean gender;  

    public Person(String name, int age, boolean gender) {  
        this.name = name;  
        this.age = age;  
        this.gender = gender;  
    }  

    @Override  
    public boolean equals(Object obj) {  
        if (this == obj) return true;  
        if (obj == null || getClass() != obj.getClass()) return false;  
        Person other = (Person) obj;  
        return age == other.age && gender == other.gender && Objects.equals(name, other.name);  
    }  

    @Override  
    public String toString() {  
        return name + "-" + age + "-" + gender;  
    }  
}  

第二步:实现 Student 类

class Student extends Person {  
    String stuNo;  
    String clazz;  

    public Student(String name, int age, boolean gender, String stuNo, String clazz) {  
        super(name, age, gender);  
        this.stuNo = stuNo;  
        this.clazz = clazz;  
    }  

    @Override  
    public String toString() {  
        return "Student:" + super.toString() + "-" + stuNo + "-" + clazz;  
    }  

    @Override  
    public boolean equals(Object obj) {  
        if (!super.equals(obj)) return false;  
        if (obj == null || getClass() != obj.getClass()) return false;  
        Student other = (Student) obj;  
        return Objects.equals(stuNo, other.stuNo) && Objects.equals(clazz, other.clazz);  
    }  
}  

第三步:实现 Company 类

class Company {  
    String name;  

    public Company(String name) {  
        this.name = name;  
    }  

    @Override  
    public String toString() {  
        return name;  
    }  

    @Override  
    public boolean equals(Object obj) {  
        if (this == obj) return true;  
        if (obj == null || getClass() != obj.getClass()) return false;  
        Company other = (Company) obj;  
        return Objects.equals(name, other.name);  
    }  
}  

第四步:实现 Employee 类

class Employee extends Person {  
    double salary;  
    Company company;  
    DecimalFormat df = new DecimalFormat("#.#");  

    public Employee(String name, int age, boolean gender, double salary, Company company) {  
        super(name, age, gender);  
        this.salary = salary;  
        this.company = company;  
    }  

    @Override  
    public String toString() {  
        return "Employee:" + super.toString() + "-" + (company != null ? company : "null") + "-" + df.format(salary);  
    }  

    @Override  
    public boolean equals(Object obj) {  
        if (!super.equals(obj)) return false;  
        if (obj == null || getClass() != obj.getClass()) return false;  
        Employee other = (Employee) obj;  
        // 比较company(处理null情况)  
        boolean companyEqual = (company == null && other.company == null) ||  
                               (company != null && other.company != null && company.equals(other.company));  
        // 比较salary(保留1位小数)  
        String salaryStr = df.format(salary);  
        String otherSalaryStr = df.format(other.salary);  
        return companyEqual && salaryStr.equals(otherSalaryStr);  
    }  
}  

第五步:主方法逻辑

import java.util.*;  
import java.text.DecimalFormat;  

public class Main {  
    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);  
        List<Person> personList = new ArrayList<>();  

        // 创建对象并添加到列表  
        while (in.hasNext()) {  
            String type = in.next();  
            if ("s".equals(type)) {  
                String name = in.next();  
                int age = in.nextInt();  
                boolean gender = in.nextBoolean();  
                String stuNo = in.next();  
                String clazz = in.next();  
                personList.add(new Student(name, age, gender, stuNo, clazz));  
            } else if ("e".equals(type)) {  
                String name = in.next();  
                int age = in.nextInt();  
                boolean gender = in.nextBoolean();  
                double salary = in.nextDouble();  
                String companyName = in.next();  
                Company company = "null".equals(companyName) ? null : new Company(companyName);  
                personList.add(new Employee(name, age, gender, salary, company));  
            } else {  
                break;  
            }  
        }  

        // 按姓名升序、年龄升序排序  
        personList.sort(Comparator.comparing(Person::getName).thenComparingInt(Person::getAge));  

        // 输出排序后的列表(调试用,非题目要求)  
        // personList.forEach(System.out::println);  

        // 处理继续指令  
        String command = in.next();  
        if ("exit".equals(command)) return;  

        // 分类并去重  
        List<Student> stuList = new ArrayList<>();  
        List<Employee> empList = new ArrayList<>();  

        for (Person p : personList) {  
            if (p instanceof Student) {  
                Student s = (Student) p;  
                if (!stuList.contains(s)) stuList.add(s);  
            } else if (p instanceof Employee) {  
                Employee e = (Employee) p;  
                if (!empList.contains(e)) empList.add(e);  
            }  
        }  

        // 输出结果  
        System.out.println("stuList");  
        stuList.forEach(System.out::println);  
        System.out.println("empList");  
        empList.forEach(System.out::println);  
    }  
}  

整体流程图:

整体代码:

import java.util.*;
import java.text.*;

class Person{
    String name;
    int age;
    boolean gender;

    public Person(String name, int age, boolean gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public boolean equals(Object obj){
        if(this == obj) return true;
        if(obj == null || this.getClass()!=obj.getClass()) return false;
        Person o = (Person) obj;
        if(this.name.equals(o.name) && this.age == o.age && this.gender == o.gender) return true;
        return false;
    }

    public String toString() {
        return name + "-" + age + "-" + gender;
    }
}

class Student extends Person{
    String stuNo;
    String clazz;

    public Student(String name, int age, boolean gender, String stuNo, String clazz) {
        super(name, age, gender);
        this.stuNo = stuNo;
        this.clazz = clazz;
    }

    public String toString(){
        return "Student:" + super.toString() + "-" + this.stuNo + "-" + this.clazz;
    }
    public boolean equals(Object obj){
        if(this == obj) return true;
        if(obj == null) return false;
        if(super.equals(obj)){
            Student o = (Student) obj;
            if(this.stuNo.equals(o.stuNo) && this.clazz.equals(o.clazz)) return true;
        }
        return false;
    }
}

class Company{
    String name;

    public Company(String name){
        this.name = name;
    }

    public String toString(){
        return name;
    }

    public boolean equals(Object obj){
        if(this==obj) return true;
        if(obj==null||this.getClass()!=obj.getClass()) return false;
        Company o = (Company) obj;
        if(this.name.equals(o.name)) return true;
        return false;
    }
}

class Employee extends Person{
    double salary;
    Company company;

    public Employee(String name, int age, boolean gender, double salary, Company company){
        super(name,age,gender);
        this.salary = salary;
        this.company = company;
    }

    public String toString(){
        return "Employee:" + super.toString() + "-" + this.company + "-" + this.salary;
    }

    public boolean equals(Object obj){
        if(this==obj) return true;
        if(obj==null||this.getClass()!=obj.getClass()) return false;
        if(super.equals(obj)){
            Employee o = (Employee) obj;
            DecimalFormat df = new DecimalFormat("#.#");
            if(this.company==null&&o.company==null) return df.format(this.salary).equals(df.format(o.salary));
            if(this.company==null||o.company==null) return false;
            if(this.company.equals(o.company)) return df.format(this.salary).equals(df.format(o.salary));
        }
        return false;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        List<Person> personList = new ArrayList<>();

        while(in.hasNext()){
            String x = in.next();
            if(x.equals("s")){
                String name = in.next();
                int age = in.nextInt();
                boolean gender = in.nextBoolean();
                String stuNo = in.next();
                String clazz = in.next();
                Person t = new Student(name, age, gender, stuNo, clazz);
                personList.add(t);
            }else if(x.equals("e")){
                String name = in.next();
                int age = in.nextInt();
                boolean gender = in.nextBoolean();
                double salary = in.nextDouble();
                String companyname = in.next();
                Company company = new Company(companyname);
                Person t = new Employee(name, age, gender, salary, company);
                personList.add(t);
            }else {
                break;
            }
        }

        Collections.sort(personList, new Comparator<Person>() {
            public int compare(Person o1, Person o2) {
                int number = o1.name.compareTo(o2.name);
                if(number!=0){
                    return number;
                }else{
                    return o1.age-o2.age;
                }
            }
        });
        for(Person i:personList){
            System.out.println(i.toString());
        }

        String cc = in.next();
        if(cc.equals("exit")||cc.equals(("return"))) {
            return;
        }

        List<Student> stuList = new ArrayList<>();
        List<Employee> empList = new ArrayList<>();
        for(Person e:personList){
            if(e instanceof Student){
                Student student = (Student) e;
                int flag = 1;
                for(Student ee:stuList){
                    if(ee.equals(e)){
                        flag = 0;
                        break;
                    }
                }
                if(flag==1){
                    stuList.add(student);
                }
            }else if(e instanceof Employee){
                Employee employee = (Employee) e;
                int flag = 1;
                for(Employee ee:empList){
                    if(ee.equals(e)){
                        flag = 0;
                        break;
                    }
                }
                if(flag==1){
                    empList.add(employee);
                }
            }
        }

        System.out.println("stuList");
        for(Student i:stuList){
            System.out.println(i.toString());
        }

        System.out.println("empList");
        for(Employee i:empList){
            System.out.println(i.toString());
        }
    }
}

思考:在本次人员管理系统的设计中,关于类的结构设计与方法逻辑的思考贯穿始终,核心可从面向对象原则、代码复用性、数据处理细节三方面展开。从面向对象设计原则来看,抽象类 Person 的定义是关键基础。将 name、age、gender 等公共属性及 toString、equals 等公共行为封装在父类中,遵循 “单一职责原则”,使子类仅需关注特有属性(如 Student 的 stuNo、Employee 的 company),避免代码冗余。继承机制在此体现得淋漓尽致:Student 和 Employee 通过 extends 关键字复用父类构造方法与基础逻辑,同时通过重写 toString 和 equals 方法实现差异化功能,符合 “开闭原则”(对扩展开放,对修改关闭)。例如,Employee 的 equals 方法先调用父类逻辑判断基础属性,再补充自身属性的比较,这种 “父类定义骨架,子类填充细节” 的模式极大提升了代码的可维护性。关于sumAllArea 与 sumAllPerimeter 方法的设计决策(类比前序形状问题),本题虽未直接涉及类似工具方法,但可延伸思考:若存在统计所有人员共性数据的需求(如计算平均年龄),此类方法应放置于独立的工具类(如 Utils)或主类(Main)中,声明为 static 以避免依赖对象实例,体现 “工具方法” 的无状态性。这种设计与本题中排序逻辑(使用 Collections.sort)的思路一致 —— 将与集合操作相关的通用逻辑抽离,保持业务类的纯净性。数据处理细节方面,equals 方法的全面性是核心难点。需逐层判断:父类属性是否相等(通过 super.equals)、子类特有属性是否相等、引用类型(如 Company、String)是否为 null 及如何安全比较。例如,Employee 中对 company 的比较需分三种情况:两者均为 null、仅一方为 null、均不为 null 但 name 不同,通过 Objects.equals 简化非空判断逻辑,避免冗长的 if-else 分支。对 salary 保留 1 位小数的处理(使用 DecimalFormat)则体现了 “精度控制” 的重要性 —— 直接比较 double 可能因浮点误差导致逻辑错误,格式化后转为字符串比较更可靠,这一细节在财务、统计类场景中尤为关键。输入处理的空值兼容(如输入 “null” 时赋值为 null)与类型安全转换(如 instanceof 判断)是程序健壮性的保障。例如,创建 Company 对象时,若输入为 “null” 则直接赋值为 null,而非创建名称为 “null” 的实例,确保数据逻辑正确。分类去重时,通过 List.contains 结合 equals 方法过滤重复对象,本质上是利用多态特性 —— 父类引用在运行时动态绑定子类对象,实现 “同一接口,不同实现” 的去重逻辑。从代码扩展性角度看,若未来新增角色(如 Teacher 类),只需继承 Person 类并实现特有属性与方法,无需修改现有排序、分类逻辑,充分体现多态的优势。排序逻辑中使用 Comparator.comparing 的链式调用,使排序规则清晰易读,若需调整排序优先级(如先按年龄再按姓名),只需修改比较器顺序,符合 “最少修改原则”。综上,本次设计通过继承构建类层次结构,利用多态实现统一接口下的差异化行为,结合 equals 与 toString 方法的合理重写,以及对输入输出、集合操作的细节处理,形成了结构清晰、可扩展的人员管理系统。这些实践不仅加深了对面向对象核心概念的理解,也为复杂系统设计提供了可复用的方法论,例如 “抽象公共接口→子类实现细节→统一集合管理→多态处理业务” 的开发模式,可广泛应用于各类领域模型的构建中。

posted @ 2025-05-21 11:41  取名字比写博客还难  阅读(88)  评论(0)    收藏  举报