Menu
Coddy logo textTech

Переопределение методов

Часть раздела Объектно-ориентированное программирование путешествия по Swift на Coddy. Урок 23 из 57.

Подкласс может заменить унаследованный метод собственной версией. Требуется ключевое слово override, которое предотвращает случайную замену метода:

class Animal {
    func sound() -> String { "..." }
}

class Dog: Animal {
    override func sound() -> String { "Woof" }
}

class Cat: Animal {
    override func sound() -> String { "Meow" }
}

print(Dog().sound())
print(Cat().sound())
print(Animal().sound())

Вывод:

Woof
Meow
...

super.method() вызывает версию метода суперкласса из переопределения, поэтому подкласс может дополнить унаследованное поведение, а не заменять его целиком:

class Report {
    func text() -> String { "Sales: 120" }
}

class SignedReport: Report {
    override func text() -> String {
        super.text() + " (signed by Ada)"
    }
}

print(SignedReport().text())

Вывод:

Sales: 120 (signed by Ada)

Вычисляемые свойства также можно переопределять с помощью override var:

class Shape {
    var sides: Int { 0 }
    var summary: String { "\(sides) sides" }
}

class Triangle: Shape {
    override var sides: Int { 3 }
}

print(Triangle().summary)

Вывод:

3 sides

Переопределение выполняется даже тогда, когда метод вызывается из унаследованного кода: приведённый выше summary написан в Shape, но использует sides объекта Triangle. Swift всегда вызывает версию фактического объекта, и именно это делает переопределение полезным:

class Greeter {
    func name() -> String { "someone" }
    func greet() -> String { "Hello, \(name())" }
}

class AdaGreeter: Greeter {
    override func name() -> String { "Ada" }
}

let g: Greeter = AdaGreeter()
print(g.greet())

Вывод:

Hello, Ada
challenge icon

Задание

Легко

Notification имеет метод render(), который возвращает [info] text. Объявите подклассы Warning, чей render() возвращает [warn] TEXT (текст в верхнем регистре), и Reminder, который добавляет сохранённое значение minutes, а его render() возвращает результат суперкласса, за которым следует (in 10 min), используя super.

Предоставленный код считывает строки info,text, warn,text или remind,text,10, создаёт соответствующий объект в массиве Notification и выводит render() для каждого объекта.

Ваш код должен находиться в файлах Notification.swift, Warning.swift и Reminder.swift. В main.swift находится предоставленный код ввода/вывода, и его нельзя редактировать.

Попробуйте сами

// Предоставленный код ввода/вывода: оставьте его как есть
var input: [String] = []
while let line = readLine() { input.append(line) }
var all: [Notification] = []
for line in input {
    let p = line.split(separator: ",").map(String.init)
    switch p[0] {
    case "warn": all.append(Warning(text: p[1]))
    case "remind":
        let r = Reminder(text: p[1])
        r.minutes = Int(p[2])!
        all.append(r)
    default: all.append(Notification(text: p[1]))
    }
}
for n in all { print(n.render()) }
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Песочница Swift