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