super e costruttori
Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 19 di 57.
super.method() richiama la versione di un metodo della superclasse dall'interno di un override. Una sottoclasse può estendere il comportamento ereditato invece di sostituirlo:
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)"
}All'interno di main:
println(Notification("backup done").render())
println(Reminder("meeting", 10).render())Output:
[info] backup done
[info] meeting (in 10 min)Ogni sottoclasse deve chiamare un costruttore della superclasse. Con un costruttore primario, la chiamata fa parte dell'intestazione, : Base(arguments), e gli argomenti possono essere calcolati a partire dai parametri della sottoclasse:
open class Product(val name: String, val price: Int)
class Discounted(name: String, price: Int, val percent: Int) :
Product(name, price * (100 - percent) / 100)All'interno di main:
val tea = Discounted("tea", 500, 10)
println("${tea.name} ${tea.price} (${tea.percent}% off)")Output:
tea 450 (10% off)La creazione procede dall'alto verso il basso nella gerarchia: vengono eseguiti prima gli inizializzatori delle proprietà della superclasse e i blocchi init, poi quelli della sottoclasse:
open class Base(name: String) {
init { println("Base init for $name") }
}
class Child(name: String) : Base(name.uppercase()) {
init { println("Child init for $name") }
}All'interno di main:
Child("kit")Output:
Base init for KIT
Child init for kitUna classe senza costruttore primario chiama la superclasse da ciascun costruttore secondario con super(...), oppure delega a un altro dei propri costruttori 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)
}All'interno di main:
val r = Rect(3)
println("${r.name} ${r.w}x${r.h}")Output:
rect 3x3Poiché la superclasse viene inizializzata per prima, non dovrebbe chiamare membri open dal suo costruttore o da init. L'override viene eseguito prima che le proprietà della sottoclasse abbiano ricevuto i loro valori:
open class Base {
init { println("Base sees: ${describe()}") }
open fun describe() = "base"
}
class Child : Base() {
val label = "child"
override fun describe() = "label is $label"
}All'interno di main:
Child()Output:
Base sees: label is nullSfida
FacileNotification(text) ha un metodo open render() che restituisce [info] text. Completa le sottoclassi: render() di Warning restituisce [warn] TEXT con il testo in maiuscolo, mentre Reminder, che memorizza anche minutes, restituisce il risultato della superclasse seguito da (in 10 min), usando super.
Il codice fornito legge righe info,text, warn,text o remind,text,10, crea l'oggetto corrispondente in un unico List<Notification> e stampa render() per ciascuno.
Il tuo codice va inserito in Notification.kt, Warning.kt e Reminder.kt. Main.kt contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
fun main() {
// Codice di input/output fornito: lascialo così com'è
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())
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiCostruttori primariBlocchi init e convalidaCostruttori secondariRiepilogo - Tessera della biblioteca4Ereditarietà
Classi aperte e sottoclassiRidefinizione dei membrisuper e costruttoriClassi astratteRiepilogo - Elenco del personale2Proprietà e incapsulamento
Accessor personalizzatiModificatori di visibilitàSetter privatilazy e lateinitRipasso - Conto bancario5Interfacce
Dichiarare le interfacceMetodi predefinitiInterfacce multipleLe interfacce come tipiRiepilogo - Metodi di pagamento8Tipi generici
Funzioni genericheClassi genericheVincoli sui tipiVarianza con in e outRiepilogo - Coda con priorità11Progetto: Gestione della biblioteca
Libri e sociPrendere in prestito i libriEsercitati da solo: Playground Kotlin