比较器内部的良好做法是铸造吗?

Is good practice casting inside comparator?

我有下一个 classes

class Person {  private String name; }

class Student extends Person {  private int studyPlace;  private int studyYears; }

class Worker extends Person {  private String workPosition;  private int experienceYears; }

我想将所有这些 class 对象存储在一个集合中 List<Person> persons.

为了排序我想使用下一个class


class DurationComparator implements Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        if (o1 == null && o2 == null) {
            return 0;
        }
        if (o1 == null) {
            return 1;
        }
        if (o2 == null) {
            return -1;
        }

        int p1 = 0;
        int p2 = 0;

        if (o1 instanceOf Student){
            p1 = ((Student) o1).getStudyYears();
        }


        if (o1 instanceOf Worker){
            p1 = ((Worker) o1).getExperienceYears();
        }


        if (o2 instanceOf Student){
            p2 = ((Student) o2).getStudyYears();
        }


        if (o2 instanceOf Worker){
            p2 = ((Worker) o2).getExperienceYears();
        }

        return p2 - p1;

    }
}

我知道 LSP 原理。将 SubClass 类型转换为 Base 类型是一种好习惯吗?

我觉得不太好。您的 'Person' 比较器必须了解所有可能的子类。后面加'Manager extends Person'的时候,你得把比较器修好,不然所有的Manager都一样。如果有其他人没有某种 'years' 值,则不清楚您将如何比较它。

一个更好的方法是让 Person 有一个抽象方法返回用于比较的数字。

 class Person {
    …
    int getYears();
    …
 }

那么比较器的主体是(忽略空注意事项)只是

 return o2.getYears() - o1.getYears();

这是对 Person 的侵入,因为首先它向 Person 添加了一个您以前没有的方法,其次它强制每个 Person 子类公开一个合适的 'years' 值。另一方面,如果您不这样做,那么能够比较任意 Persons 的想法就没有根据。