Menu
Coddy logo textTech

final et hiérarchies

Fait partie de la section Programmation orientée objet du Journey Swift de Coddy. Leçon 25 sur 57.

final empêche toute redéfinition ultérieure. Une final func ne peut être redéfinie dans aucune sous-classe, et une final class ne peut pas du tout être dérivée :

class Account {
    final func id() -> String { "ACC" }   // ne peut pas être redéfinie
}

final class Receipt { }                  // ne peut pas être sous-classée
// class GiftReceipt: Receipt { }        // erreur : héritage d'une classe finale

Marquez une méthode final lorsque les sous-classes ne doivent pas la modifier, par exemple une méthode qui impose une règle. D’autres méthodes peuvent toujours être redéfinies pour personnaliser les détails :

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]))

Sortie :

100
90

Les hiérarchies peuvent comporter plusieurs niveaux. Une méthode est recherchée depuis la propre classe de l’objet vers les classes parentes, et la première implémentation trouvée est exécutée :

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())

Sortie :

swims
eats

Gardez les hiérarchies peu profondes. Les chaînes profondes sont difficiles à suivre, car le comportement d’un objet est réparti sur de nombreuses classes. Lorsque des types partagent un comportement sans relation « est-un », les protocoles (chapitre suivant) sont généralement l’outil le plus approprié.

// profond et fragile
class A { }
class B: A { }
class C: B { }
class D: C { }      // qu'est-ce que D hérite, et d'où ?
challenge icon

Défi

Facile

Discount possède une méthode final apply(to:) qui renvoie le prix moins amount(for:), sans jamais descendre en dessous de 0, et amount(for:) renvoie 0. Déclarez PercentOff (percent stocké, montant = prix multiplié par percent / 100) et FixedOff (value stocké, montant = value), chacun avec un initialiseur et une redéfinition de amount(for:). apply(to:) lui-même reste dans Discount.

Le code fourni lit le prix, puis les remises p,10 ou f,300, applique chacune au prix et affiche 1000 -> 900.

Votre code doit se trouver dans Discount.swift, PercentOff.swift et FixedOff.swift. main.swift contient le code fourni pour les entrées et les sorties et ne peut pas être modifié.

Essayez vous-même

// Code d'entrée/sortie fourni : le garder tel quel
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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Playground Swift