Menu
Coddy logo textTech

Initialiseurs et super

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

Lorsqu’une sous-classe ajoute une propriété stockée sans valeur par défaut, elle a besoin de son propre initialiseur. Elle définit d’abord ses propres propriétés, puis appelle l’initialiseur de la superclasse avec 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)")

Sortie :

Pip false

L’ordre est important : les propriétés de la sous-classe doivent avoir des valeurs avant l’exécution de super.init, et les propriétés héritées ne peuvent être utilisées qu’après. Swift vérifie cela au moment de la compilation :

init(name: String, canFly: Bool) {
    // print(self.name)      // erreur : self utilisé avant super.init
    self.canFly = canFly     // 1. propriétés propres
    super.init(name: name)   // 2. superclasse
    print(self.name)         // 3. maintenant tout peut être utilisé
}

Une sous-classe qui définit son propre initialiseur n’hérite plus de ceux de la superclasse. Une sous-classe peut également remplacer un initialiseur ayant les mêmes paramètres en le déclarant 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)

Résultat :

0
30

Chaque niveau d’une hiérarchie initialise sa propre partie et transmet le reste à sa superclasse, de sorte que chaque propriété de la chaîne reçoit une valeur exactement une fois :

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

Sortie :

City Cabs: 4 wheels, 5 seats
challenge icon

Défi

Facile

Product stocke name et price (en centimes). Déclarez la sous-classe DiscountedProduct avec un percent stocké. Son initialiseur prend name, price et percent, stocke percent et appelle super.init avec le prix déjà réduit du pourcentage (arrondi à l’entier inférieur). Un percent en dehors de 0-100 est considéré comme égal à 0. Ajoutez une méthode label() dans DiscountedProduct qui renvoie tea: 450 (10% off).

Le code fourni lit des lignes name,price,percent, crée un DiscountedProduct pour chacune et affiche label().

Votre code doit se trouver dans Product.swift et DiscountedProduct.swift. main.swift contient le code d’entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

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