Forma concisa de implementar la misma función para un tipo de retorno de subclase.
Tengo una anulación del operador de multiplicación en mi clase base.
open class Tuple(
open val x: Double,
open val y: Double,
open val z: Double,
open val w: Double
) {
open operator fun times(scalar: Double) = Tuple(x * scalar, y * scalar, z * scalar, w)
}
Me gustaría que esta anulación del operador funcione exactamente de la misma manera para las subclases.
data class Point(
override val x: Double,
override val y: Double,
override val z: Double
) : Tuple(x, y, z, 1.0) {
Intento 1:
override operator fun times(scalar: Double) = Point(x * scalar, y * scalar, z * scalar)
Intento 2:
private fun toPoint(other: Tuple) = Point(other.x, other.y, other.z)
operator fun times(scalar: Double) = toPoint(super.times(scalar))
}
Pero en lugar de eso, quiero que devuelva la subclase, lo cual requiere un subconjunto de parámetros de la clase base para ser instanciada.
¿Existe alguna forma de escribir solo una función y hacer que devuelva el tipo correspondiente según el tipo de clase de entrada?
davy.ai
Sí, esto se puede lograr utilizando una técnica llamada tipo de retorno covariante. Para hacer que la anulación del operador de multiplicación funcione de la misma manera para las subclases, simplemente podemos anular la función
times()
en la subclase y cambiar su tipo de retorno al tipo de subclase correspondiente.Aquí tienes un ejemplo de cómo se puede hacer:
Observa que hemos cambiado el tipo de retorno de la función
times()
aPoint
. Esto es posible porquePoint
es una subclase deTuple
, y así podemos utilizar el tipo de retorno covariante para devolver el tipo de subclase correspondiente.Ahora, si creamos una instancia de la clase
Point
y llamamos a la funcióntimes()
en ella, devolverá un objeto de tipoPoint
en lugar de un objeto de tipoTuple
:De esta manera, podemos tener una sola función que funcione para todas las subclases y devuelva el tipo de subclase correspondiente.