מאתחלים ו־super
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 24 מתוך 57.
כשמחלקת משנה מוסיפה מאפיין מאוחסן ללא ערך ברירת מחדל, היא זקוקה לאתחל משלה. תחילה היא מגדירה את המאפיינים שלה ואז קוראת למאתחל של מחלקת-העל באמצעות super.init(...):
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Bird: Animal {
let canFly: Bool
init(name: String, canFly: Bool) {
self.canFly = canFly
super.init(name: name)
}
}
let p = Bird(name: "Pip", canFly: false)
print("\(p.name) \(p.canFly)")פלט:
Pip falseלסדר יש חשיבות: למאפייני תת-המחלקה חייבים להיות ערכים לפני שהפקודה super.init מופעלת, וניתן להשתמש במאפיינים שעברו בירושה רק אחר כך. Swift בודקת זאת בזמן הקומפילציה:
init(name: String, canFly: Bool) {
// print(self.name) // שגיאה: שימוש ב-self לפני super.init
self.canFly = canFly // 1. מאפיינים של המחלקה עצמה
super.init(name: name) // 2. מחלקת־העל
print(self.name) // 3. כעת אפשר להשתמש בהכול
}לאחר שמחלקת משנה מגדירה אתחול משלה, היא כבר לא יורשת את האתחולים של מחלקת-העל. מחלקת משנה יכולה גם לדרוס אתחול עם אותם פרמטרים, ולסמן אותו בתור override init:
class Timer {
var seconds: Int
init(seconds: Int) { self.seconds = seconds }
}
class SafeTimer: Timer {
override init(seconds: Int) {
super.init(seconds: max(0, seconds))
}
}
print(SafeTimer(seconds: -5).seconds)
print(SafeTimer(seconds: 30).seconds)פלט:
0
30כל רמה בהיררכיה מאתחלת את החלק שלה ומעבירה את השאר למחלקת-העל שלה, כך שכל מאפיין בשרשרת מקבל ערך בדיוק פעם אחת:
class Vehicle {
let wheels: Int
init(wheels: Int) { self.wheels = wheels }
}
class Car: Vehicle {
let seats: Int
init(seats: Int) {
self.seats = seats
super.init(wheels: 4)
}
}
class Taxi: Car {
let company: String
init(company: String) {
self.company = company
super.init(seats: 5)
}
}
let t = Taxi(company: "City Cabs")
print("\(t.company): \(t.wheels) wheels, \(t.seats) seats")פלט:
City Cabs: 4 wheels, 5 seatsאתגר
קלProduct שומר את name ואת price (בסנטים). הכריזו על תת-המחלקה DiscountedProduct עם percent שמור. המאתחל שלה מקבל את name, את price ואת percent, שומר את percent וקורא ל-super.init עם המחיר לאחר הפחתת האחוז (בעיגול כלפי מטה). ערך percent מחוץ לטווח 0-100 נחשב ל-0. הוסיפו מתודה label() ב-DiscountedProduct שמחזירה tea: 450 (10% off).
הקוד שסופק קורא שורות בפורמט name,price,percent, יוצר DiscountedProduct עבור כל שורה ומדפיס את label().
הקוד שלכם ייכתב בקבצים Product.swift ו-DiscountedProduct.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.
נסו בעצמכם
// קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map { String($0) }
let item = DiscountedProduct(name: p[0], price: Int(p[1])!, percent: Int(p[2])!)
print(item.label())
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
תרגלו בעצמכם: Swift אונליין