Menu
Coddy logo textTech

final והיררכיות

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

final מונע דריסות נוספות. אי אפשר לדרוס final func באף מחלקת משנה, ואי אפשר לרשת מ־final class כלל:

class Account {
    final func id() -> String { "ACC" }   // לא ניתן לדרוס אותה
}

final class Receipt { }                  // לא ניתן ליצור ממנה תת־מחלקה
// class GiftReceipt: Receipt { }        // שגיאה: ירושה ממחלקת final

סמנו מתודה ב-final כשאסור למחלקות יורשות לשנות אותה, למשל מתודה שאוכפת כלל. עדיין אפשר לדרוס מתודות אחרות כדי להתאים אישית פרטים:

class Checkout {
    final func total(_ prices: [Int]) -> Int {
        let sum = prices.reduce(0, +)
        return sum - discount(sum)
    }
    func discount(_ sum: Int) -> Int { 0 }
}

class SaleCheckout: Checkout {
    override func discount(_ sum: Int) -> Int { sum / 10 }
}

print(Checkout().total([50, 50]))
print(SaleCheckout().total([50, 50]))

פלט:

100
90

להיררכיות יכולות להיות כמה רמות. מחפשים את המתודה החל במחלקה של האובייקט עצמו ומעלה, והיישום הראשון שנמצא הוא זה שרץ:

class Animal {
    func move() -> String { "moves" }
    func eat() -> String { "eats" }
}
class Bird: Animal {
    override func move() -> String { "flies" }
}
class Penguin: Bird {
    override func move() -> String { "swims" }
}

let p = Penguin()
print(p.move())
print(p.eat())

פלט:

swims
eats

שמרו על היררכיות שטוחות. קשה לעקוב אחר שרשראות עמוקות, כי ההתנהגות של אובייקט אחד מפוזרת על פני מחלקות רבות. כשטיפוסים חולקים התנהגות בלי יחס של is-a, פרוטוקולים (בפרק הבא) הם בדרך כלל הכלי המתאים יותר.

// עמוק ושברירי
class A { }
class B: A { }
class C: B { }
class D: C { }      // מה D יורשת, ומאיפה?
challenge icon

אתגר

קל

ל־Discount יש מתודה final בשם apply(to:) שמחזירה את המחיר פחות amount(for:), אך לעולם לא פחות מ־0, ו־amount(for:) מחזירה 0. הצהר על PercentOff (עם percent שמור, סכום = מחיר כפול אחוז חלקי 100) ועל FixedOff (עם value שמור, סכום = value), לכל אחד מהם אתחול ודריסת amount(for:). apply(to:) עצמה נשארת ב־Discount.

הקוד שסופק קורא את המחיר ואז מחיל הנחות p,10 או f,300, מחיל כל אחת מהן על המחיר ומדפיס 1000 -> 900.

יש לכתוב את הקוד שלך בקבצים Discount.swift, PercentOff.swift ו־FixedOff.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.

נסו בעצמכם

// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
let price = Int(input[0])!
for line in input.dropFirst() {
    let p = line.split(separator: ",").map(String.init)
    let d: Discount = p[0] == "p" ? PercentOff(percent: Int(p[1])!) : FixedOff(value: Int(p[1])!)
    print("\(price) -> \(d.apply(to: price))")
}
quiz iconבחנו את עצמכם

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

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

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