2016-07-05 5 views
3

Предположим, у меня есть класс без полей, но несколько методов. Например, класс, который только реализующий interface:Что такое подходящая реализация equals() для класса без полей?

public class SomeClass implements SomeInterface 
{ 
    @Override 
    public void someMethod(int param) {...} 

    @Override 
    public int getSomeValue(OtherClass param) {return ...;} 
} 

Теперь я хочу, чтобы переопределить equals() для этого. Могу ли я всегда возвращать true, утверждая, что «поскольку объекты не имеют какого-либо состояния, они всегда равны»?

Реализация так:

@Override 
public boolean equals(Object other) 
{ 
    if (null == other || !(other instanceof SomeClass)) 
     return false; 
    return true; 
} 


Edit: Поскольку некоторые люди спрашивали о намерении за этим, я собираюсь более подробно рассказать о контексте, в котором возник этот вопрос:

Этот класс является слушателем событий. Я создаю экземпляр и передаю его в качестве слушателя к асинхронному запросу вместе с некоторыми другими данными, инкапсулированными в Object с именем Config.

Другими словами, у меня есть класс с именем Config, который состоит из SomeClass и некоторых других данных.

public class Config 
{ 
    SomeClass someClass; 
    int otherData; 
    //... 

    @Override 
    public boolean equals(Object other) {/*???*/} 
} 

На самом деле я хотел бы реализовать equals для этого Config класса (Потому что я хочу, чтобы предотвратить повторные запросы). Но так как одна часть Config - это пример SomeClass Мне было интересно, что с этим делать.


Боковой вопрос: Если SomeClass является вложенным классом и имеют неявную ссылку на его ограждающей класса, что делать тогда? (В моем контексте это так.)

+7

Зачем переопределять 'equals' вообще для такого класса? Вероятно, вы не собираетесь хранить экземпляры этого класса в наборе или в ключах карты, не так ли? – Eran

+0

Я бы сказал, что они равны тогда и только тогда, когда они одного класса, например. если бы у меня был класс ClassClass Extends SomeClass' и переопределить некоторые методы, они не должны быть равны. –

+0

Обычно я защищаю противоположное (чтобы избежать статических методов), но если класс имеет ** никакие поля ** вообще; то мне интересно, почему вам нужно будет создавать экземпляры этого класса в первую очередь. – GhostCat

ответ

7

Только возвращение true плохая реализация, так как это будет означать, что любой экземпляр вашего класса равно любой другой объект, который, вероятно, не то, что вы хотели. Кроме того, он разорвет equals 'общий договор о коммутативности, так как mySomeClass.equals("Mousa") вернет true, а "Mousa".equals(mySomeClass) вернется false.

Поскольку SomeClass не имеет государства, реализующего его метод equals, это вопрос вкуса. Наличие любых двух экземпляров SomeClass является равным между собой, это разумный выбор, хотя предлагаемая вами реализация может быть улучшена.Как other instanceof SomeClass вернется false если other является null, метод может быть просто переписать в виде

@Override 
public boolean equals(Object other) { 
    return other instanceof SomeClass; 
} 

Кроме того, следует отметить, что для того, чтобы поддерживать общий договор двух равных объектов, имеющих один и тот же hashCode(), вы должны переопределите этот метод. Например:

@Override 
public int hashCode() { 
    return SomeClass.class.hashCode(); 
} 

С другой стороны, это также вполне разумно, чтобы решить, что с SomeClass не имеет состояния, единственный способ два объекта могут быть равны друг другу, если они указывают на один и тот же экземпляр (то есть, поведение оператора ==). Этот подход используется другим известным классом без гражданства, который вы, возможно, знаете из JDK - java.lang.Object.

+0

Ошибка вашего хэш-кода для подклассов? – matt

+0

@matt Хорошая точка. Использование 'getClass()', вероятно, недостаточно устойчиво. Я отредактировал свой ответ, чтобы улучшить его. – Mureinik

+0

О вашем первом абзаце, я рассмотрел это при моей реализации: 'if (null == other ||! (Другой экземпляр SomeClass)) return false;' – Mousa

4

Это семантический вопрос: что значит иметь два объекта этого класса? (Может быть, даже полезно реализовать его как одиночный?)

Если их можно использовать взаимозаменяемо, их действительно можно считать равными. (Не забудьте переопределить hashCode().) Но также вы можете сохранить исходное определение, которое исходит от Object.

+0

Согласен. Сделайте шаг назад на мгновение ... вам действительно нужно больше одного экземпляра класса без учета штата? Почему вы помещаете несколько копий в «Коллекция», или почему еще вы их сравниваете? – vikingsteve

+0

Спасибо, я понимаю, что ты говоришь. Фактически это меняет мою точку зрения и может думать лучше. Также я добавил дополнительную информацию о контексте вопроса, и я хотел бы получить ваше мнение по моему конкретному делу. – Mousa

Смежные вопросы