Menu
Coddy logo textTech

Podklasy

Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 22 z 57.

Dziedziczenie pozwala klasie bazować na innej klasie. class Dog: Animal czyni Dog podklasą nadklasy Animal: pies ma wszystkie właściwości i metody zwierzęcia, a także te, które dodaje Dog:

class Animal {
    var name: String
    init(name: String) { self.name = name }
    func describe() -> String { "\(name) is an animal" }
}

class Dog: Animal {
    func fetch() -> String { "\(name) fetches the ball" }
}

let rex = Dog(name: "Rex")
print(rex.describe())
print(rex.fetch())

Wynik:

Rex is an animal
Rex fetches the ball

Podklasa, która nie dodaje żadnych przechowywanych właściwości, dziedziczy inicjalizatory nadklasy, dlatego Dog(name:) działa bez init w Dog. Dziedziczenie modeluje relację jest-a: każdy pies jest zwierzęciem, więc Dog może być używany wszędzie tam, gdzie oczekiwany jest Animal:

class Animal {
    var name: String
    init(name: String) { self.name = name }
}

class Cat: Animal {}
class Dog: Animal {}

let pets: [Animal] = [Cat(name: "Tom"), Dog(name: "Rex")]
for pet in pets { print(pet.name) }

Wynik:

Tom
Rex

Tylko klasy obsługują dziedziczenie; struktury i wyliczenia nie mogą dziedziczyć. Klasa może mieć co najwyżej jedną nadklasę, ale nadklasa może mieć wiele podklas, tworząc hierarchię:

class Vehicle { var wheels = 0 }
class Car: Vehicle { }        // Car jest pojazdem typu Vehicle
class Bike: Vehicle { }       // Bike jest pojazdem typu Vehicle
// struct Truck: Vehicle { }  // błąd: struktury nie mogą dziedziczyć

Umieść w klasie bazowej wszystko, co jest wspólne dla wszystkich klas pochodnych, a w każdej klasie pochodnej tylko różnice. Gdy jeden typ tak naprawdę nie jest rodzajem drugiego, dziedziczenie nie jest właściwym narzędziem; często lepiej sprawdza się właściwość przechowująca obiekt drugiego typu.

class Shape {
    var name: String
    init(name: String) { self.name = name }
    func label() -> String { "a \(name)" }
}

class Square: Shape {
    var side = 1.0
    func area() -> Double { side * side }
}

let s = Square(name: "square")
s.side = 3
print(s.label())
print(s.area())

Wynik:

a square
9.0
challenge icon

Wyzwanie

Łatwy

Employee przechowuje name i salary oraz ma metodę raise(by:), która zwiększa wynagrodzenie o określony procent (zaokrąglając w dół). Zadeklaruj podklasę Manager, która dodaje przechowywaną właściwość reports (tablicę imion, początkowo pustą) oraz metodę addReport(_:), a także metodę teamSize(), która zwraca liczbę raportów.

Dostarczony kod tworzy menedżera na podstawie pierwszego wiersza (name,salary), dodaje każde kolejne imię jako raport, przyznaje podwyżkę o 10% i wypisuje Ada earns 5500 and leads 2.

Umieść swój kod w plikach Employee.swift i Manager.swift. Plik 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) }
let head = input[0].split(separator: ",").map(String.init)
let boss = Manager(name: head[0], salary: Int(head[1])!)
for name in input.dropFirst() { boss.addReport(name) }
boss.raise(by: 10)
print("\(boss.name) earns \(boss.salary) and leads \(boss.teamSize())")
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Edytor online Swift