#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. Да, родитель<*> вполне приемлем. Не стесняйтесь принять мой ответ, если он ответил на ваш вопрос.