Me gustaría lograr algo en lo que pudiera llamar a una clase de datos con un tipo Int o BigDecimal . Así por ejemplo:
data class Money(val amount: Int, val currencyCode: CurrencyCode) { fun toSmallestUnit(): Int = when (this.currencyCode) { CurrencyCode.USD -> this.amount * 100 CurrencyCode.EUR -> this.amount * 100 } } Aquí me gustaría poder enviar tanto Int como BigDecimal como una cantidad a la clase de datos Money , y luego tener una función toSmallestUnit diferente para cada tipo. ¿Cómo puedo lograr esto en Kotlin?
Una forma de hacerlo es así
data class Money<T>(val amount: T, val currencyCode: CurrencyCode) { fun toSmallestUnit(): T = when(amount) { is Int -> { when (this.currencyCode) { CurrencyCode.USD -> (this.amount * 100) as T CurrencyCode.EUR -> (this.amount * 100) as T } } is BigInteger -> { when (this.currencyCode) { CurrencyCode.USD -> this.amount.multiply(BigInteger("100")) as T CurrencyCode.EUR -> this.amount.multiply(BigInteger("100")) as T } } else -> { amount } } } toSmallestUnit devolverá el tipo de resultado correcto según el tipo. Pero como puede ver, permite crear Money de cualquier tipo.
Cada vez que usa esta clase en el código, el compilador tiene que saber qué amount de tipo es para que pueda hacer algo con ella. Si estuviéramos trabajando con sus propias clases, podría definir una interfaz que ambas implementaran, pero esto no es posible con Int/BigDecimal.
Por lo tanto, le propongo que diseñe su clase para que simplemente use BigDecimal como el tipo de amount y proporcione constructores y propiedades para permitirle convertir desde Int.
Este es solo un ejemplo. No estoy seguro de cómo tiene sentido convertir una moneda en BigDecimal a un número entero.
data class Money(val amount: BigDecimal, val currencyCode: CurrencyCode) { constructor(amount: Int, currencyCode: CurrencyCode): this(amount.toBigDecimal(), currencyCode) val intAmount: Int get() = amount.toInt() fun toSmallestUnit(): Int = when (this.currencyCode) { CurrencyCode.USD -> intAmount * 100 CurrencyCode.EUR -> intAmount * 100 } }