Kotlin — Возвращаемый Тип Для Общего Наследования

#kotlin #generics #inheritance #gson

Вопрос:

У меня есть общий родительский класс:

  open class Parent<T>{/*...*/}
 

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

 class Derived1 : Parent<Foo1> {/*...*/}
class Derived2 : Parent<Foo2> {/*...*/}
 

где Foo1 и Foo2-это некоторые классы, определенные в другом месте

Теперь мне нужно создать функцию, которая возвращает другой производный класс на основе некоторого входного параметра:

 fun getDerived(derived: SomeEnumType): Parent{
    //return the correct derived class
}
 

Конечно, строка выше не будет компилироваться, потому что Parent требует общего параметра. Производные классы не одного типа, поэтому я бы не ожидал, что смогу справиться с этим полиморфно. Как я могу этого достичь? Я знаком с котлином.Все, что угодно, но это похоже на обман.

Если это поможет, я использую этот шаблон для анализа json в правильном дочернем классе с помощью библиотеки gson (путем переопределения десериализатора).

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

1. На самом деле нет способа сделать то, что ты пытаешься сделать. Если вы не знаете, какой родительский тип находится в том месте, где вы вызываете эту функцию (и, предположительно, вы этого не знаете, потому что он просто содержится в некотором перечислении, которое может иметь любое значение), то компилятор тоже не может знать. Вы сможете только безопасно вернуться Parent<*> , что, скорее всего, будет для вас в основном бесполезно.

Ответ №1:

Вам могло бы сойти с Parent<*> рук, но если есть связь между Foo1 и Foo2 (например, расширение общего интерфейса Buzz ), то вы могли бы использовать что-то вроде. Parent<out Buzz>

IIRC, <*> это как подстановочный знак Java <?> . Отсутствие ограничения типа ответа будет означать, что вам понадобятся некоторые охранники типов на месте вызова вашей функции getDerived , чтобы сделать ответ проверяемым.

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

1. к сожалению, между этими Фу нет реальной связи (если только я не заставлю их для этой цели, что кажется плохой идеей). Родитель<*> немного более сдерживающий, чем котлин. В любом случае, возможно, это лучшая идея

2. Да, родитель<*> вполне приемлем. Не стесняйтесь принять мой ответ, если он ответил на ваш вопрос.