Что означает ключевое слово super в переопределении метода equals()?
Есть класс Point, в котором переопределён метод equals, так, что сравниваются координаты x & y. Далее расширяем его до ColorPoint, и уже в нём переопределяем equals так, чтобы помимо, очевидно, координат, сравнивались бы ещё и цвета. Код этого переопределения (из одной лекции) выглядит так:
@Override
public boolean equals(Object o) {
if (!(o instanceof ColorPoint)) return false;
return super.equals(o) && ((ColorPoint) o).color == color;
}
Я впервые столкнулся с таким контекстом использования ключевого слова "super". Правильно я понимаю, что на псевдокоде последнюю строчку можно записать так:
return this.equalsБазовогоКлассаPoint(o) && ((ColorPoint) o).color == color;
И если да, то как бы её можно было переписать, не используя слова super?
return ((Point) this).equals(o) && ((ColorPoint) o).color == color; //StackOverflowError
Почему, кстати?
Ответы (1 шт):
Да, вы правильно понимаете, что это вызов метода из класса, от которого данный унаследован.
Без использования super никак не обойтись, если метод называется так же.
У вас может быть ссылка типа Point или даже Object, которая указывает на экземпляр ColorPoint:
ColorPoint colorpoint = new ColorPoint(...);
Point point = colorPoint;
Object object = point;
Вызов метода всегда происходит в зависимости от типа объекта, у которого он вызывается, а не типа ссылки, которая используется, поэтому все три вызова сделают то же самое:
colorpoint.equals(other);
point.equals(other);
object.equals(other);
Выражение this и (Color)this отличается только типом выражения, а ссылка остается на тот же объект. Т.е. разница между ними как между colorpoint и point из примера выше, только в типе ссылки. И при вызове метода будет использован метод определенный в классе объекта на который реально указывает ссылка (независимо от типа самой ссылки).
С вашим изменением происходит вызов того же метода рекурсивно без конца (до исчерпания доступной памяти для стека).