Klasy otwarte i podklasy
Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 17 z 57.
Dziedziczenie pozwala jednej klasie bazować na innej. Podklasa otrzymuje wszystkie właściwości i metody swojej nadklasy i może dodać własne. Klasy w Kotlinie są domyślnie zamknięte, więc klasę trzeba oznaczyć jako open, zanim inna klasa będzie mogła ją rozszerzyć:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name) {
fun fetch() = "$name fetches the ball"
}Wewnątrz main:
val rex = Dog("Rex")
println(rex.describe())
println(rex.fetch())Wynik:
Rex is an animal
Rex fetches the ballclass Dog(name: String) : Animal(name) oznacza, że Dog rozszerza Animal i przekazuje name do konstruktora nadklasy. Parametr nie ma val, ponieważ właściwość już istnieje w Animal. Klasy, która nie jest open, nie można rozszerzać:
class Plant(val name: String)
// class Tree(name: String) : Plant(name) // błąd: ten typ jest finalny, więc nie można po nim dziedziczyć
open class Vehicle(val wheels: Int)
class Bike : Vehicle(2) // przekazuje stałą wartość
class Truck(val load: Int) : Vehicle(6) // dodaje własną właściwośćDog jest Animal, więc instancji podklasy można używać wszędzie tam, gdzie oczekiwany jest typ nadklasy. Jedna List<Animal> może przechowywać psy, koty i zwykłe zwierzęta, a każdy element ma składowe Animal:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name)
class Cat(name: String, val indoor: Boolean) : Animal(name)Wewnątrz main:
val pets: List<Animal> = listOf(Dog("Rex"), Cat("Tom", true), Animal("Generic"))
for (p in pets) println(p.describe())Wynik:
Rex is an animal
Tom is an animal
Generic is an animalDziedziczenie modeluje relację jest-jednym-z: pies jest zwierzęciem, konto oszczędnościowe jest kontem. Gdy jedna klasa tylko korzysta z innej (samochód ma silnik), zamiast tego nadaj jej właściwość tego typu. Klasy w Kotlinie są domyślnie zamknięte, więc klasa przeznaczona do rozszerzania oznacza to za pomocą open, a każda inna klasa zachowuje bezpieczne zachowanie wobec podklas.
open class Account(val owner: String)
class SavingsAccount(owner: String) : Account(owner) // jest rodzajem: dziedziczenie
class Engine(val horsepower: Int)
class Car(val engine: Engine) // ma: właściwośćWyzwanie
ŁatwyManager powtarza to, co Employee już ma. Oznacz Employee jako open i zmień Manager w jego podklasę: Manager(name: String, salary: Int) przekazuje obie wartości do Employee i zachowuje tylko to, co nowe: prywatną listę nazw podwładnych, z metodami addReport(name) i teamSize(). W Employee metoda raise(percent) zwiększa pensję o podany procent, zaokrąglając w dół, a describe() zwraca Ada earns 5500.
Dostarczony kod tworzy menedżera na podstawie pierwszego wiersza (name,salary), dodaje każde kolejne imię jako podwładnego, przyznaje 10% podwyżki i wypisuje Ada earns 5500 and leads 2, a następnie sprawdza, czy menedżer jest obiektem typu Employee.
Twój kod umieść w plikach Employee.kt i Manager.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 (name, salary) = input[0].split(",")
val boss = Manager(name, salary.toInt())
for (report in input.drop(1)) boss.addReport(report)
boss.raise(10)
println("${boss.describe()} and leads ${boss.teamSize()}")
println("a manager is an employee: ${(boss as Any) is Employee}")
}
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