Я очень плохо знаком с концепцией обобщения, поэтому недавно я наткнулся на некоторую запутанную ситуацию.
Я хочу написать функцию, которая отправляет файл на удаленный сервер. Файл может быть изображением или аудио. Разница в отправке будет заключаться только в том, как мы работаем с параметрами файла (ширина и высота изображения в зависимости от продолжительности звука) и устанавливаем тип сообщения. Поэтому было вполне естественно написать общую функцию для обоих вариантов использования.
Допустим, у меня есть некоторый класс (в данном случае запечатанный класс для простых when
проверок), который имеет несколько наследников.
sealed class MessageData
data class MessageAudioData(
val duration: Float
) : MessageData()
data class MessageImageData(
var width: Float,
var height: Float
) : MessageData()
Изначально я хотел написать такую функцию:
fun <T : MessageData> sendFile(fileData: T) {
...
}
Но с введением запечатанного класса проверка when
не работает, как положено. Поэтому я переписал свою функцию так:
fun sendFile(fileData: MessageData) {
...
}
when
проверка работает, и у меня, похоже, нет проблем с ней.
Но потом я подумал, верно ли это способ go, и в чем разница. Я читал о дисперсии, и я думаю, что это будет иметь значение в классе (с in
и out
), но, вероятно, я что-то упускаю. Может ли кто-нибудь помочь мне лучше понять это?
РЕДАКТИРОВАТЬ : Я думаю, что мне нужно немного прояснить ситуацию, так как я слишком много внимания уделяю запечатанному классу.
Меня больше всего интересовало использование и варианты использования обобщенных c функций с ограничениями. О работе именно с типом внутри функции? Я имею в виду, что я могу иметь interface I
, а затем class A
и class B
реализовать этот интерфейс, а затем написать функцию для работы с ними. Кажется, мне не нужно писать шаблон c, я могу просто передать параметр типа I
, и он будет работать как с fun example(A())
, так и fun example(B())
.