重写方法
本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 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 中,但它使用的是 Triangle 的 sides。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挑战
简单Notification 有一个方法 render(),它会返回 [info] text。声明子类 Warning,它的 render() 会返回 [warn] TEXT(将文本转换为大写字母),以及子类 Reminder,它会存储额外的 minutes,并使用 super 让 render() 返回超类的结果,后面跟着 (in 10 min)。
提供的代码会读取 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()) }
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Swift 在线编辑器