jmu-Java-PTA题解 (jmu-Java-03面向对象基础-05-覆盖) 网安2312陈卓

问题要求

Java每个对象都继承自Object,都有equals、toString等方法。
现在需要定义PersonOverride类并覆盖其toString与equals方法。

1. 新建PersonOverride类

a. 属性:String name、int age、boolean gender,所有的变量必须为私有(private)。

b. 有参构造方法,参数为name, age, gender

c. 无参构造方法,使用this(name, age,gender)调用有参构造方法。参数值分别为"default",1,true

d.toString()方法返回格式为:name-age-gender

e. equals方法需比较name、age、gender,这三者内容都相同,才返回true.

2. main方法

2.1 输入n1,使用无参构造方法创建n1个对象,放入数组persons1。
2.2 输入n2,然后指定name age gender。每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果不存在,才将该对象放入数组persons2。
2.3 输出persons1数组中的所有对象
2.4 输出persons2数组中的所有对象
2.5 输出persons2中实际包含的对象的数量
2.5 使用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));输出PersonOverride的所有构造方法。

提示:使用ArrayList代替数组大幅复简化代码,请尝试重构你的代码。

输入样例:

1
3
zhang 10 true
zhang 10 true
zhang 10 false

输出样例:

default-1-true
zhang-10-true
zhang-10-false
2
[public PersonOverride(), public PersonOverride(java.lang.String,int,boolean)]

关键点

  • 方法覆盖:正确覆盖toString()和equals()方法,确保对象比较和字符串表示符合需求。
  • 对象比较:equals()方法需处理好引用相等、空值检查、类型转换和属性比较。
  • 集合去重:利用ArrayList的contains()方法结合重写的equals()实现自动去重。
  • 反射应用:通过Class.getConstructors()获取类的所有构造方法。

解题步骤

第一步:设计 PersonOverride 类

创建PersonOverride类,封装属性并提供构造方法和重写方法:

class PersonOverride {
    private String name;
    private int age;
    private boolean gender;

    public PersonOverride() {
        this("default", 1, true);
    }

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

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

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

第二步:编写 Main 类进行输入处理和输出

使用ArrayList存储对象,处理输入并按要求输出结果:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 处理第一组输入:无参构造创建对象
        int n1 = scanner.nextInt();
        ArrayList<PersonOverride> persons1 = new ArrayList<>();
        for (int i = 0; i < n1; i++) {
            persons1.add(new PersonOverride());
        }
        
        // 处理第二组输入:有参构造创建对象并去重
        int n2 = scanner.nextInt();
        ArrayList<PersonOverride> persons2 = new ArrayList<>();
        for (int i = 0; i < n2; i++) {
            String name = scanner.next();
            int age = scanner.nextInt();
            boolean gender = scanner.nextBoolean();
            PersonOverride person = new PersonOverride(name, age, gender);
            if (!persons2.contains(person)) {
                persons2.add(person);
            }
        }
        
        // 输出结果
        persons1.forEach(System.out::println);
        persons2.forEach(System.out::println);
        System.out.println(persons2.size());
        System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
        
        scanner.close();
    }
}

整体流程图:

整体代码:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
class PersonOverride{
    private String name;
    private int age;
    private boolean gender;

    public PersonOverride(){
        this("default",1,true);
    }

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

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

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

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n1 = in.nextInt();
        ArrayList<PersonOverride> person1 = new ArrayList<PersonOverride>();
        for(int i=0;i<n1;i++){
            PersonOverride e = new PersonOverride();
            person1.add(e);
        }
        int n2 = in.nextInt();
        ArrayList<PersonOverride> person2 = new ArrayList<PersonOverride>();
        for(int i=0;i<n2;i++){
            String name = in.next();
            int age = in.nextInt();
            boolean gender = in.nextBoolean();
            PersonOverride e = new PersonOverride(name,age,gender);
            if(!person2.contains(e))
            {
                person2.add(e);
            }
        }
         for (PersonOverride str : person1) {
            System.out.println(str);
        }
        for (PersonOverride str : person2) {
            System.out.println(str);
        }
        System.out.println(person2.size());
        System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
    }
}

思考:类的封装与方法重写是解决问题的基础。将PersonOverride的属性设为私有,通过构造方法和公共方法实现数据的封装与访问,这是面向对象编程中确保数据安全性的核心原则。而重写toString()和equals()方法则体现了对对象行为的自定义 ——toString()为对象提供了可读性更强的字符串表示,方便调试和输出;equals()则重新定义了对象相等的逻辑,使得集合框架中的contains()方法能够正确判断对象是否重复,这是实现去重功能的关键。这里需要特别注意的是,在重写equals()时必须遵循对称性、一致性等原则,同时建议一并重写hashCode()以避免潜在的集合操作问题(本题中因ArrayList的contains()方法仅依赖equals(),故未强制要求,但实际开发中应保持两者逻辑一致)。其次,集合框架的选择与应用显著提升了代码的简洁性。使用ArrayList代替普通数组,无需手动处理数组的初始化长度、扩容等细节,尤其是在处理动态增长的对象集合时(如persons2的去重添加),ArrayList的动态特性和内置方法(如add()、contains())大幅简化了代码逻辑。对比原始问题中使用数组的场景,集合框架的优势在于其封装好的数据结构操作,减少了开发者对底层实现的关注,转而更聚焦于业务逻辑(如去重规则)。此外,通过forEach循环遍历集合,结合 Lambda 表达式(如System.out::println),进一步提升了代码的可读性和简洁性,体现了 Java 8 之后函数式编程的特性。反射机制的引入为程序增添了动态性。通过PersonOverride.class.getConstructors()获取类的构造方法并输出,展示了 Java 在运行时自省(Introspection)的能力。这一特性在框架开发、依赖注入(如 Spring)等场景中至关重要,它允许程序在不预先知道类具体结构的情况下,动态获取类的元信息,实现更灵活的代码扩展。本题中虽仅用于输出构造方法列表,但揭示了反射在代码分析、动态创建对象等场景中的潜力。本题的实现不仅是对 Java 基础语法的实践,更是对面向对象设计原则(如单一职责、开闭原则)的初步探索。通过合理选择数据结构、善用语言特性(如重写方法、反射)和框架工具(如集合类),我们能够编写出更简洁、健壮且易于维护的代码,这为后续开发复杂应用奠定了重要基础。在实际项目中,类似的思考方式可延伸至更大规模的类设计与系统架构,帮助开发者构建更高效的软件解决方案。

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