﻿# V6056\. Implementation of 'compareTo' overloads the method from a base class\. Possibly, an override was intended\.

Анализатор выявил случай, когда метод 'compareTo' перегружает одноименный метод родительского класса, который реализует интерфейс 'Comparable<T\>'\. Скорее всего, перегрузка метода родительского класса не то, что подразумевалось разработчиком\. 

Рассмотрим пример класса, который вместо переопределения метода осуществляет перегрузку:

```cpp
public class Human implements Comparable<Human>
{
  private String mName;
  private int mAge;
  ....
  Human(String name, int age)
  {
    mName = name;
    mAge = age;
  }
  ....
  public int compareTo(Human human)
  {
    int result = this.mName.compareTo(human.mName);
    if (result == 0)
    {
      result = Integer.compare(this.mAge, human.mAge);
    }
    return result;
  }
}

public class Employee extends Human
{
  int mSalary;
  ....
  public Employee(String name, int age, int salary) {
    super(name, age);
    mSalary = salary;
  }
  ....
  public int compareTo(Employee employee)
  {
    return Integer.compare(this.mSalary, employee.mSalary);
  }
}
```

Итак, у нас есть два класса: базовый 'Human' и дочерний 'Employee'\. 'Human' реализует интерфейс 'Comparable<Human\>' и определяет метод 'compareTo'\. Далее дочерний класс 'Employee' расширяет базовый класс и перегружает метод 'compareTo'\. Результат метода сравнения таков:

* отрицательное число \- если текущий объект меньше сравниваемого;
* 0 \- если объекты равны;
* положительное число \- если текущий объект больше сравниваемого;

Из этого может выйти следующий эффект:

1\) Если мы представим объекты 'Employee' через ссылку на базовый класс, то вызвав метод 'compareTo' мы не достигнем нужного сравнения объектов: 

```cpp
Human emp1 = new Employee("Andrew", 25, 33000);
Human emp2 = new Employee("Madeline", 29, 31000);
System.out.println(emp1.compareTo(emp2));
```

На экран будет выведено \-12, и получается, что объект emp1 логически меньше emp2\. Ведь это не так\. Скорее всего, программистом подразумевалось, что эти объекты будут сравниваться на основе поля 'mSalary', и в таком случае, результат был бы противоположным\. Это произошло из\-за того, что программист перегрузил метод сравнения, а не переопределил\. И когда произошел вызов метода, то вызвался метод из класса 'Human'\.

2\) Известно, что списки элементов, которые реализуют интерфейс 'Comparable<T\>', могут автоматически быть отсортированы с помощью 'Collections\.sort'/'Arrays\.sort', а также такие элементы могут быть использованы в качестве ключей отсортированных коллекций, без явного указания компоратора\. И в случае такой перегрузки сортировка будет осуществляться не так, как задумывалась, судя по реализации сравнения в дочернем классе\. Опасность в том, что в таких случаях происходит неявный вызов метода сравнения, и сразу ошибку можно не найти\. 

Выполним следующий код:

```cpp
List<Human> listEmployees = new ArrayList<>();
listEmployees.add(new Employee("Andrew", 25, 33000));
listEmployees.add(new Employee("Madeline", 29, 31000));
listEmployees.add(new Employee("Hailey", 45, 55000));
System.out.println("Before: ");
listEmployees.forEach(System.out::println);
Collections.sort(listEmployees);
System.out.println("After: ");
listEmployees.forEach(System.out::println);
```

На экран будет выведен следующий текст:

```cpp
Before: 
Name: Andrew; Age: 25; Salary: 33000
Name: Madeline; Age: 29; Salary: 31000
Name: Hailey; Age: 45; Salary: 55000
After: 
Name: Andrew; Age: 25; Salary: 33000
Name: Hailey; Age: 45; Salary: 55000
Name: Madeline; Age: 29; Salary: 31000
```

Как видно из вывода, сортировка была осуществлена не по полю 'mSalary'\. И все происходит по той же самой причине\.

Решение этой проблемы сводится к тому, что метод сравнения должен быть переопределен, а не перегружен\. Например:

```cpp
public class Employee extends Human
{
  ....
  public int compareTo(Human employee)
  {
    if (employee instanceof Employee)
    {
      return Integer.compare(this.mSalary,
                             ((Employee)employee).mSalary);
    }

    return -1;
  }
  ....
}
```



И тогда будет все работать так, как задумывалось изначально\.

В первом случае вывод будет 1 \(emp1 логически больше emp2\)\.

Во втором случае вывод будет следующим:

```cpp
Name: Andrew; Age: 25; Salary: 33000
Name: Madeline; Age: 29; Salary: 31000
Name: Hailey; Age: 45; Salary: 55000
After: 
Name: Madeline; Age: 29; Salary: 31000
Name: Andrew; Age: 25; Salary: 33000
Name: Hailey; Age: 45; Salary: 55000
```