Inicjalizatory i super
Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 24 z 57.
Gdy podklasa dodaje przechowywaną właściwość bez wartości domyślnej, potrzebuje własnego inicjalizatora. Najpierw ustawia własne właściwości, a następnie wywołuje inicjalizator nadklasy za pomocą super.init(...):
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Bird: Animal {
let canFly: Bool
init(name: String, canFly: Bool) {
self.canFly = canFly
super.init(name: name)
}
}
let p = Bird(name: "Pip", canFly: false)
print("\(p.name) \(p.canFly)")Wynik:
Pip falseKolejność ma znaczenie: właściwości podklasy muszą mieć wartości, zanim zostanie wywołane super.init, a z odziedziczonych właściwości można korzystać dopiero po tym wywołaniu. Swift sprawdza to w czasie kompilacji:
init(name: String, canFly: Bool) {
// print(self.name) // błąd: self użyte przed super.init
self.canFly = canFly // 1. własne właściwości
super.init(name: name) // 2. klasa nadrzędna
print(self.name) // 3. teraz można używać wszystkiego
}Gdy podklasa definiuje własny inicjalizator, nie dziedziczy już inicjalizatorów nadklasy. Podklasa może też przesłonić inicjalizator z tymi samymi parametrami, oznaczając go jako override init:
class Timer {
var seconds: Int
init(seconds: Int) { self.seconds = seconds }
}
class SafeTimer: Timer {
override init(seconds: Int) {
super.init(seconds: max(0, seconds))
}
}
print(SafeTimer(seconds: -5).seconds)
print(SafeTimer(seconds: 30).seconds)Wynik:
0
30Każdy poziom hierarchii inicjalizuje swoją część i przekazuje resztę swojej nadklasie, dzięki czemu każda właściwość w łańcuchu otrzymuje wartość dokładnie raz:
class Vehicle {
let wheels: Int
init(wheels: Int) { self.wheels = wheels }
}
class Car: Vehicle {
let seats: Int
init(seats: Int) {
self.seats = seats
super.init(wheels: 4)
}
}
class Taxi: Car {
let company: String
init(company: String) {
self.company = company
super.init(seats: 5)
}
}
let t = Taxi(company: "City Cabs")
print("\(t.company): \(t.wheels) wheels, \(t.seats) seats")Wynik:
City Cabs: 4 wheels, 5 seatsWyzwanie
ŁatwyProduct przechowuje name i price (w centach). Zadeklaruj podklasę DiscountedProduct z przechowywanym percent. Jej inicjalizator przyjmuje name, price i percent, przechowuje percent i wywołuje super.init z ceną już obniżoną o procent (zaokrągloną w dół). Wartość percent spoza zakresu 0-100 jest traktowana jako 0. Dodaj metodę label() w DiscountedProduct, która zwraca tea: 450 (10% off).
Dostarczony kod odczytuje wiersze name,price,percent, tworzy dla każdego obiektu DiscountedProduct i wypisuje label().
Twój kod umieść w plikach Product.swift i DiscountedProduct.swift. main.swift zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map { String($0) }
let item = DiscountedProduct(name: p[0], price: Int(p[1])!, percent: Int(p[2])!)
print(item.label())
}
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 klasMetody i selfInicjalizatoryKlasy są referencjamiPowtórzenie — karta biblioteczna4Hermetyzacja
Kontrola dostępuTylko do odczytu z zewnątrzOchrona stanuInicjalizatory, które mogą zawieśćPodsumowanie — konto bankowe7Polimorfizm i typy generyczne
PolimorfizmRzutowanie typówFunkcje generyczneTypy generycznePodsumowanie – kalkulator kształtów2Struktury i typy wartościowe
StrukturySemantyka wartościMetody modyfikująceStruktura czy klasaPodsumowanie – element inwentarza5Dziedziczenie
PodklasyPrzesłanianie metodInicjalizatory i superfinal i hierarchiePodsumowanie — hierarchia pracowników8Standardowe protokoły
CustomStringConvertibleEquatableComparableHashablePodsumowanie — własne sortowanie11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Swift