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 基础语法的实践,更是对面向对象设计原则(如单一职责、开闭原则)的初步探索。通过合理选择数据结构、善用语言特性(如重写方法、反射)和框架工具(如集合类),我们能够编写出更简洁、健壮且易于维护的代码,这为后续开发复杂应用奠定了重要基础。在实际项目中,类似的思考方式可延伸至更大规模的类设计与系统架构,帮助开发者构建更高效的软件解决方案。

浙公网安备 33010602011771号