Kotlin — Универсальный абстрактный класс, реализующий универсальный интерфейс

#java #android #kotlin #interface #jvm

Вопрос:

У меня есть это abstract class , которое принимает interface как универсальный тип:

 abstract class A<T: GenericInterface> : T {
  ...
}
 

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

 Only classes and interfaces may serve as supertypes
 

Есть ли какой-нибудь обходной путь в этом случае?

Я хочу, чтобы мои классы расширяли abstract class A передачу пользовательского интерфейса, который расширяется GenericInterface , и могли реализовывать методы этого пользовательского интерфейса.

Это прототип того, чего я пытаюсь достичь:

 abstract class A<T: GenericInterface> : T {
  ...
}

interface CustomInterface: GenericInterface {

  ...
}

class B: A<CustomInterface> {

  // Here I want to override CustomInterface funs

}
 

Я знаю, что всегда могу использовать этот подход:

 class B: A, CustomInterface {

  // override CustomInterface funs here

}
 

но для целей шаблона кода мне бы хотелось другое решение

Комментарии:

1. Однажды у меня была точно такая же проблема, и я не нашел способа ее решить. Вместо этого я сделал что-то вроде этого: abstract class A<T: GenericInterface> { val obj: T } . Вместо того , чтобы требовать реализации для реализации T , они должны были предоставляться T как отдельный объект. На практике они обычно все равно внедряются T , а затем возвращаются this .

2. И я думаю, что это невозможно по техническим причинам из-за стирания типа. Это не проблема, если мы сотрем тип поля, параметр функции или ее возвращаемый тип — мы можем скомпилировать его в Any / Object и привести во время выполнения. Тем не менее, мы знаем всех членов общего типа, мы просто не знаем их конкретных типов. Ваш случай сильно отличается, потому что теперь мы даже не знаем, какие методы A на самом деле есть у класса — это зависит от его параметра типа. Хотя я считаю, что можно было бы разработать язык с поддержкой такой функции, это действительно сильно отличается от «обычных» дженериков.

3. @broot Да, на данный момент это невозможно в Котлине, я думаю. Возможно, в будущем появится библиотека, которая будет генерировать классы во время компиляции.