Ghi đè phương thức
Thuộc phần Lập trình hướng đối tượng trong hành trình Swift của Coddy. Bài học 23 trên 57.
Lớp con có thể thay thế phương thức được kế thừa bằng phiên bản riêng. Cần có từ khóa override để tránh vô tình thay thế một phương thức:
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())Đầu ra:
Woof
Meow
...super.method() gọi phiên bản của lớp cha từ bên trong phần ghi đè, nhờ đó lớp con có thể bổ sung hành vi được kế thừa thay vì thay thế toàn bộ hành vi đó:
class Report {
func text() -> String { "Sales: 120" }
}
class SignedReport: Report {
override func text() -> String {
super.text() + " (signed by Ada)"
}
}
print(SignedReport().text())Đầu ra:
Sales: 120 (signed by Ada)Các thuộc tính được tính toán cũng có thể được ghi đè bằng override var:
class Shape {
var sides: Int { 0 }
var summary: String { "\(sides) sides" }
}
class Triangle: Shape {
override var sides: Int { 3 }
}
print(Triangle().summary)Đầu ra:
3 sidesPhương thức ghi đè vẫn chạy ngay cả khi được gọi từ code kế thừa: summary ở trên được viết trong Shape, nhưng lại dùng sides của Triangle. Swift luôn gọi phiên bản của đối tượng thực tế, nhờ vậy việc ghi đè trở nên hữu ích:
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())Đầu ra:
Hello, AdaThử thách
DễNotification có một phương thức (method) render() trả về [info] text. Khai báo các lớp con Warning, có render() trả về [warn] TEXT (phần văn bản viết hoa), và Reminder, lớp này lưu thêm minutes và có render() trả về kết quả của lớp cha theo sau là (in 10 min), bằng cách dùng super.
Code được cung cấp đọc các dòng info,text, warn,text hoặc remind,text,10, tạo đối tượng tương ứng trong một mảng gồm các đối tượng Notification rồi in ra render() của từng đối tượng.
Code của bạn nằm trong Notification.swift, Warning.swift và Reminder.swift. main.swift chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
// Đoạn code đầu vào/đầu ra đã cung cấp: giữ nguyên.
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()) }
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpPhương thức và selfHàm khởi tạoLớp là tham chiếuÔn tập: Thẻ thư viện2Struct và kiểu giá trị
StructNgữ nghĩa giá trịPhương thức thay đổiStruct hay classÔn tập: mặt hàng trong kho5Kế thừa
Lớp conGhi đè phương thứcHàm khởi tạo và superfinal và hệ phân cấpÔn tập: hệ phân cấp nhân viên8Các giao thức tiêu chuẩn
CustomStringConvertibleEquatableComparableHashableÔn tập: Sắp xếp tùy chỉnhTự luyện tập: Playground Swift