Menu
Coddy logo textTech

פולימורפיזם

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 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
Woof

Swift קובעת איזו מימוש להפעיל בזמן ריצה, לפי האובייקט בפועל. הטיפוס המוצהר של המשתנה אינו משנה; הטיפוס של האובייקט הוא שקובע:

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()) }
challenge icon

אתגר

קל

ל־Animal יש name, legs() (4) ו־describe(), שמחזירה את Rex has 4 legs and says Woof, שנבנה מתוך legs() ו־sound(). הכריזו על Dog (צליל Woof), על Bird (2 רגליים, צליל Tweet) ועל Snake (0 רגליים, צליל Hiss) באמצעות דריסה של legs() ו־sound() בלבד.

הקוד שסופק קורא שורות 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()) }
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: Swift אונליין