דריסת מתודות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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אתגר
קלל־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()) }
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
תרגלו בעצמכם: Swift אונליין