Menu
Coddy logo textTech

מחלקות משנה

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 22 מתוך 57.

ירושה מאפשרת למחלקה להתבסס על מחלקה אחרת. class Dog: Animal הופכת את Dog למחלקת משנה של מחלקת העל Animal: לכלב יש את כל המאפיינים והשיטות של בעל חיים, וגם את מה ש-Dog מוסיפה:

class Animal {
    var name: String
    init(name: String) { self.name = name }
    func describe() -> String { "\(name) is an animal" }
}

class Dog: Animal {
    func fetch() -> String { "\(name) fetches the ball" }
}

let rex = Dog(name: "Rex")
print(rex.describe())
print(rex.fetch())

פלט:

Rex is an animal
Rex fetches the ball

תת־מחלקה שאינה מוסיפה מאפיינים מאוחסנים יורשת את המאתחלים של מחלקת־העל, ולכן Dog(name:) פועל ללא init בתוך Dog. ירושה ממדלת יחס של הוא־סוג־של: כל כלב הוא בעל חיים, ולכן אפשר להשתמש ב־Dog בכל מקום שבו מצופה Animal:

class Animal {
    var name: String
    init(name: String) { self.name = name }
}

class Cat: Animal {}
class Dog: Animal {}

let pets: [Animal] = [Cat(name: "Tom"), Dog(name: "Rex")]
for pet in pets { print(pet.name) }

פלט:

Tom
Rex

רק מחלקות תומכות בירושה; מבנים ומניינים אינם יכולים לרשת. למחלקה יכולה להיות לכל היותר מחלקת־על אחת, אך למחלקת־על יכולים להיות תתי־מחלקות רבות, וכך נוצרת היררכיה:

class Vehicle { var wheels = 0 }
class Car: Vehicle { }        // Car הוא Vehicle
class Bike: Vehicle { }       // Bike הוא Vehicle
// struct Truck: Vehicle { }  // שגיאה: מבנים אינם יכולים לרשת

שמים במחלקת-העל את כל מה שמשותף לכל מחלקות-המשנה, ובכל מחלקת-משנה רק את ההבדלים. כשסוג אחד אינו באמת סוג של השני, ירושה היא הכלי הלא נכון; לרוב עדיף להשתמש במאפיין שמחזיק את הסוג האחר.

class Shape {
    var name: String
    init(name: String) { self.name = name }
    func label() -> String { "a \(name)" }
}

class Square: Shape {
    var side = 1.0
    func area() -> Double { side * side }
}

let s = Square(name: "square")
s.side = 3
print(s.label())
print(s.area())

פלט:

a square
9.0
challenge icon

אתגר

קל

Employee מאחסן name ו-salary, ויש לו מתודה raise(by:) שמגדילה את המשכורת באחוז מסוים (בעיגול כלפי מטה). הצהירו על תת-מחלקה בשם Manager שמוסיפה מאפיין מאוחסן reports (מערך של שמות, ריק בתחילה), מתודה addReport(_:) ומתודה teamSize() שמחזירה את מספר הדיווחים.

הקוד שסופק יוצר מנהל מהשורה הראשונה (name,salary), מוסיף כל שם מהשורות הבאות כדיווח, מעניק העלאה של 10% ומדפיס את Ada earns 5500 and leads 2.

כתבו את הקוד שלכם בקבצים Employee.swift ו-Manager.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.

נסו בעצמכם

// קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
let head = input[0].split(separator: ",").map(String.init)
let boss = Manager(name: head[0], salary: Int(head[1])!)
for name in input.dropFirst() { boss.addReport(name) }
boss.raise(by: 10)
print("\(boss.name) earns \(boss.salary) and leads \(boss.teamSize())")
quiz iconבחנו את עצמכם

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

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

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