Funciones de extensión
Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 30 de 57.
Una función de extensión añade una función a un tipo existente sin cambiar el código fuente del tipo. Su nombre se escribe después del tipo receptor y, dentro de ella, this hace referencia al receptor, que también se puede omitir:
fun String.shout() = uppercase() + "!"
fun Int.isEven() = this % 2 == 0Dentro de main:
println("hello".shout())
println(7.isEven())
println(listOf(1, 2, 3, 4).count { it.isEven() })Salida:
HELLO!
false
2Las extensiones también funcionan en tus propias clases, y las propiedades de extensión añaden propiedades calculadas. Una extensión no puede añadir estado almacenado y solo puede acceder a los miembros públicos de su receptor:
class Temperature(val celsius: Double)
val Temperature.fahrenheit: Double
get() = celsius * 9 / 5 + 32
fun Temperature.describe() = "$celsius C is $fahrenheit F"Dentro de main:
println(Temperature(100.0).describe())Salida:
100.0 C is 212.0 FLas extensiones se resuelven estáticamente: el tipo declarado de la expresión determina la extensión cuando se compila el programa, no la clase del objeto. Esta es la principal diferencia con un miembro sobrescrito:
open class Shape {
open fun member() = "shape member"
}
class Circle : Shape() {
override fun member() = "circle member"
}
fun Shape.ext() = "shape extension"
fun Circle.ext() = "circle extension"Dentro de main:
val s: Shape = Circle()
println(s.member())
println(s.ext())Salida:
circle member
shape extensionCuando la clase ya tiene un miembro con la misma firma, el miembro siempre gana. Usa miembros para el comportamiento que pertenece al tipo y puede sobrescribirse; usa extensiones para los asistentes añadidos desde fuera, como el formato de una clase que no te pertenece:
class Robot {
fun greet() = "member greet"
}
fun Robot.greet() = "extension greet"
fun Robot.wave() = "extension wave"Dentro de main:
val r = Robot()
println(r.greet())
println(r.wave())Salida:
member greet
extension waveDesafío
FácilMoney(cents) se proporciona en Money.kt. Escribe extensiones para él en MoneyExtensions.kt: las propiedades de extensión Int.dollars y Int.cents, que convierten un número en Money (12.dollars son 1200 centavos), Money.format(), que devuelve $12.50 (o -$3.05 para cantidades negativas), List<Money>.total(), que devuelve la suma como Money, y Money.split(parts), que divide en parts cantidades que difieren como máximo en un centavo, con las mayores primero.
El código proporcionado lee líneas 12 dollars o 50 cents y una última línea con el número de partes. Imprime cada cantidad, total: $12.50 y split 3: $4.17 $4.17 $4.16.
Tu código va en MoneyExtensions.kt y Money.kt. Main.kt contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
fun main() {
// Código de entrada/salida suministrado: déjalo tal como está
val input = generateSequence(::readLine).toList()
val amounts = input.dropLast(1).map { line ->
val (n, unit) = line.split(" ")
if (unit == "dollars") n.toInt().dollars else n.toInt().cents
}
for (m in amounts) println(m.format())
val total = amounts.total()
println("total: ${total.format()}")
val parts = input.last().toInt()
println("split $parts: " + total.split(parts).joinToString(" ") { it.format() })
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesConstructores primariosBloques init y validaciónConstructores secundariosRepaso - Tarjeta de biblioteca4Herencia
Clases abiertas y subclasesSobrescritura de miembrossuper y constructoresClases abstractasRepaso: directorio del personal2Propiedades y encapsulación
Accesores personalizadosModificadores de visibilidadSetters privadoslazy y lateinitRepaso: cuenta bancaria5Interfaces
Declaración de interfacesMétodos predeterminadosInterfaces múltiplesInterfaces como tiposRepaso: métodos de pago8Genéricos
Funciones genéricasClases genéricasRestricciones de tiposVariancia con in y outRepaso - Cola de prioridad11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de libros3Objetos y complementos
Declaraciones de objetosObjetos complementariosConstantes con constExpresiones de objetosRepaso: taquilla6Polimorfismo
Despacho dinámicoComprobaciones de tipos y conversiones inteligenteswhen con tiposFunciones de extensiónRepaso: cuidador del zoológicoPractica por tu cuenta: Playground de Kotlin