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 finaleMarquez 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
90Les 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
eatsGardez 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ù ?Défi
FacileDiscount 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))")
}
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
1Classes et objets
Travailler avec des fichiersDéfinir des classesMéthodes et selfInitialiseursLes classes sont des référencesRécapitulatif - Carte de bibliothèque4Encapsulation
Contrôle d’accèsLecture seule depuis l’extérieurProtection de l’étatInitialiseurs pouvant échouerRécapitulatif - Compte bancaire7Polymorphisme et génériques
PolymorphismeConversion de typeFonctions génériquesTypes génériquesRécapitulatif - Calculateur de formes2Structures et types valeur
StructuresSémantique de valeurMéthodes mutantesStructure ou classeRécapitulatif - article d’inventaire5Héritage
Sous-classesRedéfinition des méthodesInitialiseurs et superfinal et hiérarchiesRécapitulatif - hiérarchie des employés8Protocoles standard
CustomStringConvertibleEquatableComparableHashableRécapitulatif - Tri personnalisé11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livresEntraînez-vous par vous-même : Playground Swift