Menu
Coddy logo textTech

מאתחלים ו־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
challenge icon

אתגר

קל

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())
}
quiz iconבחנו את עצמכם

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

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

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