super i konstruktory
Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 19 z 57.
super.method() wywołuje wersję metody z nadklasy z wnętrza nadpisanej metody. Podklasa może rozszerzyć odziedziczone zachowanie zamiast je zastępować:
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)"
}Wewnątrz main:
println(Notification("backup done").render())
println(Reminder("meeting", 10).render())Wynik:
[info] backup done
[info] meeting (in 10 min)Każda podklasa musi wywołać konstruktor nadklasy. W przypadku konstruktora podstawowego wywołanie jest częścią nagłówka: : Base(arguments), a argumenty mogą być obliczane na podstawie parametrów podklasy:
open class Product(val name: String, val price: Int)
class Discounted(name: String, price: Int, val percent: Int) :
Product(name, price * (100 - percent) / 100)Wewnątrz main:
val tea = Discounted("tea", 500, 10)
println("${tea.name} ${tea.price} (${tea.percent}% off)")Wynik:
tea 450 (10% off)Tworzenie przebiega od góry hierarchii w dół: najpierw uruchamiane są inicjalizatory właściwości nadklasy i bloki init, a następnie podklasy:
open class Base(name: String) {
init { println("Base init for $name") }
}
class Child(name: String) : Base(name.uppercase()) {
init { println("Child init for $name") }
}Wewnątrz main:
Child("kit")Wynik:
Base init for KIT
Child init for kitKlasa bez konstruktora podstawowego wywołuje nadklasę z każdego konstruktora dodatkowego za pomocą super(...) lub deleguje do innego własnego konstruktora za pomocą 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)
}Wewnątrz main:
val r = Rect(3)
println("${r.name} ${r.w}x${r.h}")Wynik:
rect 3x3Ponieważ nadklasa jest konfigurowana jako pierwsza, nie powinna wywoływać metod open w swoim konstruktorze ani w init. Nadpisana metoda jest uruchamiana, zanim własne właściwości podklasy otrzymają wartości:
open class Base {
init { println("Base sees: ${describe()}") }
open fun describe() = "base"
}
class Child : Base() {
val label = "child"
override fun describe() = "label is $label"
}Wewnątrz main:
Child()Wynik:
Base sees: label is nullWyzwanie
ŁatwyNotification(text) ma otwartą metodę render(), która zwraca [info] text. Uzupełnij podklasy: render() klasy Warning zwraca [warn] TEXT, gdzie tekst jest zapisany wielkimi literami, a Reminder, który przechowuje również minutes, zwraca wynik nadklasy, po którym następuje (in 10 min), używając super.
Dostarczony kod odczytuje wiersze info,text, warn,text lub remind,text,10, tworzy pasujący obiekt w jednej List<Notification> i wyświetla render() dla każdego z nich.
Twój kod umieść w plikach Notification.kt, Warning.kt i Reminder.kt. Main.kt zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
fun main() {
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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())
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasKonstruktory główneBloki init i walidacjaKonstruktory dodatkowePodsumowanie — karta biblioteczna4Dziedziczenie
Klasy otwarte i podklasyNadpisywanie składowychsuper i konstruktoryKlasy abstrakcyjnePodsumowanie – katalog pracowników7Klasy specjalne
Klasy danychKlasy wyliczenioweHierarchie zapieczętowaneequals, hashCode, toStringPodsumowanie — śledzenie zamówień10Wzorce projektowe, część 2
Delegowanie za pomocą byWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Właściwości i hermetyzacja
Własne akcesoryModyfikatory widocznościPrywatne setterylazy i lateinitPowtórka – konto bankowe5Interfejsy
Deklarowanie interfejsówMetody domyślneWiele interfejsówInterfejsy jako typyPowtórzenie – metody płatności8Typy generyczne
Funkcje generyczneKlasy generyczneOgraniczenia typówKowariancja i kontrawariancja: in i outPodsumowanie — kolejka priorytetowa11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Kotlin