Java почему должен равняться входному параметру метода be Object

Я просматриваю книгу о структурах данных. В настоящее время я на графиках, а приведенный ниже код - для вершинной части графика.

class Vertex<E>{
    //bunch of methods

    public boolean equals(Object o){
         //some code
    }
}

Когда я пытаюсь реализовать этот метод equals, мой компилятор жалуется на то, что не проверяет тип параметра и просто разрешает отправку любого объекта. Мне также кажется немного странным, почему этот параметр не должен быть Vertex вместо Object. Есть ли причина, по которой автор делает это, или это какая-то ошибка или устаревший пример?

Ответ 1

@Override
public boolean equals(Object obj)
{
     if(obj == null) return false;
     else if (!(obj instanceof Vertex)) return false;
     else return // blah blah
}

Ответ 2

equals (Object) - это метод, определенный в корне - объекте. Если вы точно не соответствуете подписи, будет вызвана версия Object, когда кто-то проверяет, совпадают ли два объекта. Не то, что вы хотите.

Вероятно, вы видели другие методы (например, Comparator), где вы можете использовать точное время. Это связано с тем, что эти API были обобщенными с Java 5. Равенства не может быть, потому что это правильно, чтобы называть равными с двумя отдельными типами. Он должен возвращать значение false, но оно действительно.

Ответ 3

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

Изменить 1

Комментарий от jhlu87:
так что это не хорошая форма для записи метода equals, который имеет входной параметр вершины?

Вы можете создать свою собственную перегрузку для любого метода, включая равные, но при этом без изменения имени можно было бы сбивать с толку многих, кто предположил бы, что ваши равны - это тот, который наследует объект. Если бы это был мой код, и мне нужен более конкретный метод equals, я бы назвал его немного отличным от просто "равным", чтобы избежать путаницы.

Ответ 4

Это потому, что этот метод существовал до дженериков, поэтому для обратной компоновки он должен оставаться таким образом.

Стандартное обходное решение для наложения типа:

return obj instanceof MyClass && <some condition>;

Ответ 5

Это связано с тем, что автор переопределяет равные. Равные значения указаны в java.lang.Object и это то, от чего все классы наследуются.

Смотрите javadoc для java.lang.Object

Ответ 6

Если ваш метод не принимает аргумент типа Object, он не переопределяет версию equals по умолчанию, а скорее перегружает ее. Когда это происходит, обе версии существуют, и Java решает, какую из них использовать, основываясь на типе переменной (не фактическом типе объекта) аргумента. Итак, эта программа:

public class Thing {

    private int x;

    public Thing(int x) {
        this.x = x;
    }

    public boolean equals(Thing that) {
        return this.x == that.x;
    }

    public static void main(String[] args) {
        Thing a = new Thing(1);
        Thing b = new Thing(1);
        Object c = new Thing(1);
        System.out.println(a.equals(b));
        System.out.println(a.equals(c));
    }

}

сбивает с толку печатает true для первого сравнения (потому что b имеет тип Thing) и false для второго (потому что c имеет тип Object, даже если он содержит Thing).