super y constructores
Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 19 de 57.
super.method() llama a la versión de la superclase de un método desde dentro de una sobrescritura. Una subclase puede ampliar el comportamiento heredado en lugar de reemplazarlo:
open class Notification(val text: String) {
open fun render() = "[info] $text"
}
class Reminder(text: String, val minutes: Int) : Notification(text) {
override fun render() = super.render() + " (in $minutes min)"
}Dentro de main:
println(Notification("backup done").render())
println(Reminder("meeting", 10).render())Salida:
[info] backup done
[info] meeting (in 10 min)Cada subclase debe llamar a un constructor de la superclase. Con un constructor principal, la llamada forma parte de la cabecera, : Base(arguments), y los argumentos se pueden calcular a partir de los parámetros de la subclase:
open class Product(val name: String, val price: Int)
class Discounted(name: String, price: Int, val percent: Int) :
Product(name, price * (100 - percent) / 100)Dentro de main:
val tea = Discounted("tea", 500, 10)
println("${tea.name} ${tea.price} (${tea.percent}% off)")Salida:
tea 450 (10% off)La creación se ejecuta desde la parte superior de la jerarquía hacia abajo: los inicializadores de propiedades y los bloques init de la superclase se ejecutan primero, después los de la subclase:
open class Base(name: String) {
init { println("Base init for $name") }
}
class Child(name: String) : Base(name.uppercase()) {
init { println("Child init for $name") }
}Dentro de main:
Child("kit")Salida:
Base init for KIT
Child init for kitUna clase sin un constructor primario llama a la superclase desde cada constructor secundario con super(...), o delega en otro de sus propios constructores con this(...):
open class Shape(val name: String)
class Rect : Shape {
val w: Int
val h: Int
constructor(w: Int, h: Int) : super("rect") {
this.w = w
this.h = h
}
constructor(side: Int) : this(side, side)
}Dentro de main:
val r = Rect(3)
println("${r.name} ${r.w}x${r.h}")Salida:
rect 3x3Como la superclase se configura primero, no debería llamar a miembros open desde su constructor o init. La sobrescritura se ejecuta antes de que las propias propiedades de la subclase tengan sus valores:
open class Base {
init { println("Base sees: ${describe()}") }
open fun describe() = "base"
}
class Child : Base() {
val label = "child"
override fun describe() = "label is $label"
}Dentro de main:
Child()Salida:
Base sees: label is nullDesafío
FácilNotification(text) tiene un método abierto render() que devuelve [info] text. Completa las subclases: el render() de Warning devuelve [warn] TEXT con el texto en letras mayúsculas, y Reminder, que también almacena minutes, devuelve el resultado de la superclase seguido de (in 10 min), usando super.
El código proporcionado lee líneas info,text, warn,text o remind,text,10, construye el objeto correspondiente en una sola List<Notification> e imprime render() para cada uno.
Tu código va en Notification.kt, Warning.kt y Reminder.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: mantenlo como está
val input = generateSequence(::readLine).toList()
val notes = mutableListOf<Notification>()
for (line in input) {
val p = line.split(",")
notes.add(when (p[0]) {
"warn" -> Warning(p[1])
"remind" -> Reminder(p[1], p[2].toInt())
else -> Notification(p[1])
})
}
for (n in notes) println(n.render())
}
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 librosPractica por tu cuenta: Playground de Kotlin