В Java можно ли требовать реализации интерфейса для переопределения методов Object?

56
6

Можно ли потребовать реализации интерфейса для переопределения методов Object?


Например, если у меня есть интерфейс, который обычно будет использоваться как ключи в HashMap s, я могу потребовать, чтобы все реализации этого интерфейса переопределили методы hashCode() и equals().


Однако, если у меня есть следующий интерфейс...:


public interface MyInterface(){
@Override
public int hashCode();

@Override
public boolean equals(Object o);
}


... выполняется следующая компиляция:


public class MyImplementation(){
}

Он не требует метода для переопределения hashCode() или equals(), поскольку он наследует эти методы от Object.


Одним из подходов может быть переход на использование абстрактного класса вместо интерфейса:


public abstract class MyAbstractClass(){
@Override
public abstract int hashCode();

@Override
public abstract boolean equals(Object o);
}


Тогда любой класс, который расширяет этот абстрактный класс, должен переопределять hashCode() и equals():


// doesn't compile - requires implementation of hashCode() and equals()
public class MyClass extends MyAbstractClass {
}

// does compile
public class MyClass extends MyAbstractClass {
@Override
public int hashCode(){
// calculate hashcode
}

@Override
public boolean equals(Object o){
// check equality
}
}


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


Однако вернемся к моему первоначальному вопросу... есть ли способ потребовать реализации интерфейса для переопределения методов Object?

спросил(а) 2012-08-17T19:06:00+04:00 7 лет, 3 месяца назад
2
Решение
74

Невозможно выполнить то, что вы хотите, используя только интерфейсы.


Альтернативный (и, возможно, более ясный) способ сделать это путем принудительного использования абстрактного базового класса выглядит следующим образом:

public abstract class MyAbstractClass {
@Override public final int hashCode() { return hashCodeImpl(); }
@Override public final boolean equals(Object o) { return equalsImpl(o); }

protected abstract int hashCodeImpl();
protected abstract boolean equalsImpl(Object o);
}

ответил(а) 2012-08-17T19:19:00+04:00 7 лет, 3 месяца назад
Еще 1 ответ
32

Нет. Java не может выразить это требование. Как абстрактный класс нравится?

public abstract class MyAbstractClass(){
@Override
public int hashCode(){
return myOverrideHashCode();
}

@Override
public boolean equals(){
return myOverrideEquals();
}

protected abstract int myOverrideHashCode();

protected abstract booleans myOverrideEquals();
}

ответил(а) 2012-08-17T19:19:00+04:00 7 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема