переопределенный метод equals не вызывается

1

Рассмотрим следующие классы:

public class Base {

    protected int i = 0;

    public Base(int i) {
        this.i = i;
    }

    public Base(Base b) {
        this(b.i);
    }

    public Base foo() {
        return new Base(this);
    }
}


public class Sub extends Base {

    public Sub(int i) {
        super(i);
    }

    public Sub(Sub s) {
        super(s.i * 2);
    }

    public Base foo() {
        return this;
    }

    @Override
    public boolean equals(Object o) {
        return ((Sub) o).i == this.i;
    }

    public static void main(String[] args) {
        Base b1 = new Base(1);
        Base b2 = b1;
        Base b3 = b2.foo();
        Base b4 = new Sub(1);
        Base b5 = b4.foo();

        System.out.println(b1.equals(b3));
    }
}

Печатный результат не соответствует false. Я заметил, что переопределенный метод equals(Object o) никогда не попадается, и я подозреваю, конечно, что это проблема (в противном случае он напечатал бы true).

Почему это?

Теги:
oop
inheritance
override

2 ответа

10
Лучший ответ

Вы вызываете b1.equals(b3) - b1 - это экземпляр Base, а не Sub, так что вы не можете вызвать ваш метод переопределения.

Heck, даже b3.equals(b1) ничего не назовет на Sub, так как b3 ссылается на экземпляр Base.

Только b4 и b5 относятся к экземплярам Sub, поэтому только b4.equals(...) или b5.equals(...) вызовут ваш переопределенный метод. Кроме того, поскольку вы безоговорочно применяете метод equals, b4.equals(b1) (например) генерирует исключение, а не возвращает false.

  • 0
    Спасибо! Я понял теперь..
2

Посмотрите, как работает ваш код (в основном методе)

Base b1 = new Base(1); : - Создает новую базу (1) Объект и ссылка - b1. Позволяет называть этот объект первым объектом.

Base b2 = b1; : - создает ссылочную переменную типа Base и присваивает значение переменной b1, поэтому оба b1 и b2 ссылаются на один и тот же объект (первый объект)

Base b3 = b2.foo(); : - Создает опорную переменную типа Base b3. foo() в первом базовом объекте вызывается и возвращает новый базовый объект (второй объект), где он атрибут value = первый объект я значение атрибута

Base b4 = new Sub(1); : - Создает новый объект Sub (1), а ссылка - b4. Позволяет называть этот объект третьим объектом.

Base b5 = b4.foo(); : - создает опорную переменную типа Base b5. foo() в третьем объекте (Sub), и он возвращает свою собственную ссылку в качестве базового типа. Sub может вернуть свою собственную ссылку в качестве базы, потому что Base - это Super Class.

b1.equals(b3): - теперь вы вызывали метод equals объекта, который ссылается на b1. b1 относится к объекту Base типа (первый объект). равен методу базового объекта. Он имеет метод равных по умолчанию. (переопределенный метод находится в Sub-объекте, и это не Sub-объект.) Метод equals по умолчанию проверяет, являются ли их хэш-коды одинаковыми. b1 - первый объект, b3 - третий объект. поэтому b1 и b3 не равны.

Таким образом, вывод должен быть false.

Здесь нет никакого превалирующего действия.

Если вы изменили код следующим образом, вы можете получить переопределенный вывод

Base b1 = new Sub(1);
Base b3 = b1.foo();
Base b4 = new Sub(1);
Base b5 = b4.foo();

System.out.println(b4.equals(b3));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню