Переопределение метода equals в java

«Давайте реализуем метод equals для класса Stamp. Вам нужно переопределить метод equals класса Object. Теперь у вас небольшая проблема. Класс Object ничего не знает о штампах, поэтому он объявляет otherObject переменная параметра метода equals должна иметь тип Объект. При переопределении метода вам не разрешено изменять тип переменной параметра."

Здесь говорится, что нам не разрешено изменять тип переменной параметра. Однако, когда я использую приведенный ниже код, он дает мне правильный результат.

public class Stamps
{
  private String color;
  private int value;

  public Stamps(String color, int value)
  {
    this.color=color;
    this.value=value;
  }

    public boolean equals(Stamps other)
    {
       return color.equals(other.color)
            && value== other.value;
    }
}


public class Main
{
     public static void main(String[] args)
     {
          Stamps stamp1 = new Stamps("red",10);
          Stamps stamp2 = new Stamps("green",10);

        System.out.println(stamp1.equals(stamp2));       
     }
}

Здесь я не переопределяю метод equals(), унаследованный от класса Object, поскольку типы параметров разные. Итак, вместо того, чтобы использовать мой код, разве он не должен использовать код, унаследованный от класса Object?

Выбирается наиболее конкретная подпись, и это ваша перегрузка.

Logan 28.05.2019 19:46

Добавьте аннотацию @Override к вашему методу equals и посмотрите, что произойдет. Вы определяете свою собственную функцию, имя которой совпадает с именем Object#equals, но вы не переопределяете ее.

Benjamin Urquhart 28.05.2019 19:46

Это дает вам правильный результат для вашего конкретного кода, но для кода, который имеет дело с произвольными объектами, такими как карты и наборы, он не будет работать (и будет очень сложно отладить почему).

Louis Wasserman 28.05.2019 19:47

Измените второе выражение на Object stamp2 = new Stamps("red",10) и попробуйте запустить его снова.

RealSkeptic 28.05.2019 19:53

Попробуйте Object obj3 = new Stamps("red",10);. Обратите внимание, что переменная имеет тип Object. Также обратите внимание, что назначенный ему объект должен быть равен stamp1. Попробуйте это: попробуйте obj3.equals(stamp1), а также stamp1.equals(obj3). Я ожидаю ложь оба раза. Если я это понял, у вас неверные результаты.

Ole V.V. 28.05.2019 20:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
5
120
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Метод java.lang.Object equals принимает параметр Object. Вы не отменяете его, если заставите его принять Stamp.

Джошуа Блох расскажет вам, как правильно переопределить хэш-код equals а также в эффективном Java Глава 3.

Строго следуйте его рекомендациям. Ваш опубликованный код неверен. Вы даже не пытаетесь использовать hashCode. Их следует выполнять парами.

Ответ принят как подходящий

Когда вы пишете выражение вызова метода в Java, за ним следует сложный набор правил, чтобы определить, какой метод будет вызываться.

По сути, компилятор будет искать наиболее конкретный метод, который он может найти, который соответствует типам параметров, которые вы пытаетесь передать.

Важным в этих правилах является то, что они не предусматривают специальных методов в Object или любой другой класс. Методы в Object обрабатываются точно так же, как и любой метод, который вы определяете сами.

Итак, если вы пытаетесь вызвать метод equals для экземпляра класса Stamps, передав один экземпляр Stamps в качестве параметра, он найдет ваш метод:

boolean equals(Stamps other)

Это более конкретно, чем на Object:

boolean equals(Object other)

(«Более конкретный» неофициально определен в спецификации следующим образом: любой параметр, который вы можете передать «более конкретному» методу, также может быть передан «менее конкретному» методу, но не наоборот).

поэтому компилятор Java выберет метод equals(Stamps).

Однако, если бы вы изменили первое или второе (или оба) объявления переменных на тип Object:

Object stamp1 = new Stamps("red",10);

тогда метод equals(Stamps) не будет вызываться:

  • Для Object stamp1 это было бы связано с тем, что Java будет искать тип Object для сопоставления методов. Поскольку в equals(Object) существует только Object, это единственное возможное для вызова.
  • Для Object stamp2 это будет связано с тем, что тип параметра equals(Stamps) не будет совпадать, поэтому единственным возможным методом для вызова будет equals(Object).

Другие вопросы по теме