Можно ли написать реализацию метода equals по умолчанию в интерфейсе Kotlin? - PullRequest
3 голосов
/ 28 февраля 2020

Можно ли написать реализацию по умолчанию метода equals в интерфейсе Kotlin?

У меня есть этот код:

interface User {

  val id: String

}

И я хочу, чтобы все классы, реализующие пользователя сравнивать с использованием свойства id. Примерно так:

interface User {

  val id: String

  fun equals(other: Any?) : Boolean {
    //check type and stuff
    return id == other.id
  }

}

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

Спасибо

1 Ответ

3 голосов
/ 29 февраля 2020

Нет, боюсь, это невозможно.

Если вы попробуете свой код, компилятор пожалуется:

'equals' hides member of supertype 'Any' and needs 'override' modifier

И если вы добавите Модификатор override:

An interface may not implement a method of 'Any'

Причины немного неясны и наследуются (!) От Java.

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

Есть несколько угловых случаев: методы, определенные в Object (Java эквивалент Kotlin * Any ). Это clone () , равно () , finalize () , getClass () , hashCode () , notify () , notifyAll () , toString () и wait () . (Большинство из них редко используются непосредственно в наши дни, но, конечно, equals(), hashCode() и toString() очень важны.)

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

Точно то же самое относится к Kotlin / JVM и соответствующим методам, определенным в Any - фактически, компилятор делает это явным, выдавая ошибку, если вы попытаетесь обеспечить реализацию по умолчанию любого из этих методов, как показано выше.

Это позор, потому что есть случаи, когда реализация по умолчанию equals(), hashCode() и / или toString() будет быть чрезвычайно полезным! Но это привело бы к сложности, хрупкости и некоторым неожиданным угловым случаям; см. этот ответ для достоверного объяснения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...