多态
本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 32 课,共 57 课。
多态是指同一段代码可以处理多种类型的值,并且每个值都以自己的方式响应。下面的循环会调用 sound(),而无需知道其中包含的是哪种动物:
class Animal {
func sound() -> String { "..." }
}
class Dog: Animal {
override func sound() -> String { "Woof" }
}
class Cow: Animal {
override func sound() -> String { "Moo" }
}
let farm: [Animal] = [Dog(), Cow(), Dog()]
for a in farm { print(a.sound()) }输出:
Woof
Moo
WoofSwift 会在运行时根据实际对象决定运行哪个实现。变量的声明类型并不重要,重要的是对象的类型:
class Animal {
func sound() -> String { "..." }
}
class Cat: Animal {
override func sound() -> String { "Meow" }
}
let pet: Animal = Cat()
print(pet.sound())输出:
Meow协议为结构体和枚举提供了同样的灵活性。这里有一个函数,可以打印任意由 Drawable 值组成的列表:
protocol Drawable {
func draw() -> String
}
struct Line: Drawable {
let length: Int
func draw() -> String { String(repeating: "-", count: length) }
}
struct Box: Drawable {
func draw() -> String { "[ ]" }
}
func render(_ items: [any Drawable]) -> String {
items.map { $0.draw() }.joined(separator: " ")
}
print(render([Line(length: 3), Box(), Line(length: 1)]))输出:
--- [ ] -多态可以替代针对不同类型事物的冗长 if/switch 链。你不必先询问一个值是什么,再决定要做什么,而是让这个值去完成相应的操作。添加一种新类型时,只需添加一个新类型,而不必修改每个 switch:
// 不使用多态
if kind == "dog" { print("Woof") } else if kind == "cow" { print("Moo") }
// 使用多态
for animal in farm { print(animal.sound()) }挑战
简单Animal 有 name、legs()(4)和 describe(),后者会返回由 legs() 和 sound() 构成的 Rex has 4 legs and says Woof。通过只重写 legs() 和 sound(),声明 Dog(声音为 Woof)、Bird(2 条腿,声音为 Tweet)和 Snake(0 条腿,声音为 Hiss)。
提供的代码会读取 dog,Rex、bird,Pip 或 snake,Kaa 这样的行,将动物存储在一个 [Animal] 数组中,并为每只动物打印 describe() 的结果。
你的代码应写在 Animal.swift、Dog.swift、Bird.swift 和 Snake.swift 中。main.swift 存放提供的输入/输出代码,不能编辑。
亲手试试
// 提供的输入/输出代码:保持原样
var input: [String] = []
while let line = readLine() { input.append(line) }
var zoo: [Animal] = []
for line in input {
let p = line.split(separator: ",").map(String.init)
switch p[0] {
case "dog": zoo.append(Dog(name: p[1]))
case "bird": zoo.append(Bird(name: p[1]))
default: zoo.append(Snake(name: p[1]))
}
}
for a in zoo { print(a.describe()) }
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Swift 在线编辑器