[Java]PTA:jmu-Java-03面向对象基础-05-覆盖
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)]
代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Objects;
import java.lang.reflect.Constructor;
import java.util.Comparator;class PersonOverride{// 属性private String name;private int age;private boolean gender;// 构造方法// 有参public PersonOverride(String name, int age, boolean gender) {this.name = name;this.age = age;this.gender = gender;}// 无参public PersonOverride() {this("default",1,true);}// 方法@Overridepublic String toString() {return name + '-' + age + '-' + gender ;}@Overridepublic boolean equals(Object o) {if (o == null || getClass() != o.getClass()) return false;PersonOverride that = (PersonOverride) o;return age == that.age && gender == that.gender && Objects.equals(name, that.name);}}public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n1 = sc.nextInt();sc.nextLine();PersonOverride[] persons1 = new PersonOverride[n1];for(int i=0;i<n1;i++){persons1[i]=new PersonOverride();}for (PersonOverride person : persons1) {System.out.println(person); // 自动调用 person 的 toString() 方法}int n2 = sc.nextInt();sc.nextLine();ArrayList<PersonOverride> persons2 = new ArrayList<>();for(int i=0;i<n2;i++){String[] parts = sc.nextLine().split(" ");String name=parts[0];int age=Integer.parseInt(parts[1]);boolean gender=Boolean.parseBoolean(parts[2]);PersonOverride p=new PersonOverride(name,age,gender);boolean token = false;for (PersonOverride existing : persons2) {if (p.equals(existing)) {token = true;break;}}if (!token) {persons2.add(p);}}for (PersonOverride person : persons2) {System.out.println(person);}System.out.println(persons2.size());Constructor<?>[] constructors = PersonOverride.class.getConstructors();Arrays.sort(constructors, Comparator.comparingInt(Constructor::getParameterCount));System.out.println(Arrays.toString(constructors));sc.close();}
}
学习反思:
1、使用 Alt+Insert 快捷键重写 equals 方法的配置。
1)模板(Template)
选择 java.util.Objects.equals...sh() (Java 7 and higher),这是利用 Java 7 及以上版本 java.util.Objects 类的工具方法来实现属性相等性判断,能更简洁、安全地处理属性为 null 的情况,是比较推荐的方式。
2)对于 equals () 方法中的类类型比较,生成
instanceof 表达式:
用 instanceof 判断对象是否是某个类或其子类的实例。
比如,若类 A 有子类 B,当用 instanceof 时,B 的实例也会被认为是 A 的实例。
getClass() 比较表达式:
通过 getClass() 方法获取对象的运行时类,只有当两个对象的类完全相同时(即属于同一个类,不是子类关系),类比较才会通过。
更严格地保证了 “只有同一类的实例才可能通过 equals 比较”,符合很多场景下对 equals 方法 “类型严格相等” 的期望。
3)可用时使用 getter (G)
若勾选,生成 equals 方法时,会通过类的 getter 方法(如 getName())来获取属性值进行比较;若不勾选,则直接访问属性(比如 this.name)。
2、Class.getConstructors() 方法
Class.getConstructors() 方法返回的构造方法数组的顺序是由 Java 虚拟机决定的,通常按照构造方法的参数数量从多到少排列(有参构造在前,无参构造在后)。
这与题目的预期顺序(无参在前,有参在后)不一致。这需要我们通过 Constructor.getParameterCount() 方法获取每个构造方法的参数数量(无参构造为 0,有参构造为 3)。再结合使用 Arrays.sort() 结合比较器,按参数数量从小到大排序,确保无参构造排在前面。
首先需要导入两个类:
import java.lang.reflect.Constructor; // 导入构造方法的反射类
import java.util.Comparator; // 导入比较器接口
然后进行改写:
第一步:获取类的所有构造方法
Constructor<?>[] constructors = PersonOverride.class.getConstructors();
1)PersonOverride.class:通过 “类名.class” 的方式获取 PersonOverride 类的 Class 对象(反射的核心入口,代表类的 “元信息”)。
2)getConstructors():Class 类的方法,作用是获取当前类的所有公开(public)构造方法,返回一个 Constructor<?>[] 数组(Constructor 类代表构造方法的元信息)。
第二步:按参数数量排序构造方法
Arrays.sort(constructors, Comparator.comparingInt(Constructor::getParameterCount));
这是关键一步,用 Arrays.sort() 对构造方法数组做自定义排序,拆解两个核心部分:
1)Arrays.sort(数组, 比较器):Arrays 工具类的排序方法。
2)Comparator.comparingInt(Constructor::getParameterCount):定义 “按构造方法的参数数量从小到大排序” 的规则。
3)Constructor::getParameterCount:方法引用,获取每个构造方法的参数数量。
4)Comparator.comparingInt(...):创建一个按 int 类型值排序的比较器,这里按参数数量升序排列。
第三步:打印排序后的构造方法
System.out.println(Arrays.toString(constructors));