Les constructeurs
Apprenez à construire vos objets en leur donnant leurs valeurs initiales.
Les constructeurs, également appelés initialiseurs, sont des méthodes spéciales utilisées pour créer des instances d'une classe, d'une structure (struct), ou d'une énumération (enum). Les initialiseurs configurent les propriétés initiales de l'instance avant que celle-ci ne soit utilisée. Chaque type peut avoir plusieurs initialiseurs pour permettre différentes manières de créer une instance.
1. Initialiseur Simple
Un initialiseur simple est défini avec le mot-clé init. Il configure les propriétés de l'instance au moment de sa création.
struct Person {
var name: String
var age: Int
// Initialiseur simple
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let person = Person(name: "Alice", age: 30)
print("Nom : \(person.name), Âge : \(person.age)") // Affiche : "Nom : Alice, Âge : 30"
2. Initialiseurs avec Paramètres Optionnels
Les initialiseurs peuvent accepter des paramètres optionnels pour créer une instance avec des propriétés qui ne sont pas toujours requises.
struct Person {
var name: String
var age: Int?
// Initialiseur avec un paramètre optionnel
init(name: String, age: Int? = nil) {
self.name = name
self.age = age
}
}
let personWithAge = Person(name: "Bob", age: 25)
let personWithoutAge = Person(name: "Charlie")
print("Nom : \(personWithAge.name), Âge : \(personWithAge.age ?? 0)") // Affiche : "Nom : Bob, Âge : 25"
print("Nom : \(personWithoutAge.name), Âge : \(personWithoutAge.age ?? 0)") // Affiche : "Nom : Charlie, Âge : 0"
3. Initialiseurs avec Paramètres par Défaut
Les initialiseurs peuvent également avoir des paramètres avec des valeurs par défaut, simplifiant ainsi la création d'instances.
struct Car {
var brand: String
var year: Int
// Initialiseur avec des paramètres par défaut
init(brand: String = "Tesla", year: Int = 2024) {
self.brand = brand
self.year = year
}
}
let defaultCar = Car() // Utilise les valeurs par défaut
let customCar = Car(brand: "Ford", year: 2020)
print("Voiture par défaut : \(defaultCar.brand), \(defaultCar.year)") // Affiche : "Voiture par défaut : Tesla, 2024"
print("Voiture personnalisée : \(customCar.brand), \(customCar.year)") // Affiche : "Voiture personnalisée : Ford, 2020"
4. Initialiseurs Failsafe (Initializers with Failures)
Les initialiseurs en Swift peuvent échouer, c'est-à-dire qu'ils peuvent retourner nil s'ils ne parviennent pas à initialiser l'instance. Ces initialiseurs sont appelés failable initializers et sont définis avec init?.
struct Temperature {
var celsius: Double
// Initialiseur qui échoue si la température dépasse une certaine limite
init?(celsius: Double) {
if celsius < -273.15 {
return nil // Échec si la température est physiquement impossible
}
self.celsius = celsius
}
}
if let validTemp = Temperature(celsius: -100) {
print("Température valide : \(validTemp.celsius)°C")
} else {
print("Température invalide")
}
if let invalidTemp = Temperature(celsius: -300) {
print("Température valide : \(invalidTemp.celsius)°C")
} else {
print("Température invalide") // Affiche : "Température invalide"
}
5. Initialiseurs Désignés et de Commodité (Designated and Convenience Initializers)
a. Initialiseurs Désignés (Designated Initializers)
Un initialiseur désigné est l'initialiseur principal d'une classe ou d'une structure. Il initialise directement toutes les propriétés de la classe ou de la structure. Les classes doivent toujours avoir au moins un initialiseur désigné, sauf si elles héritent tous leurs initialiseurs d'une superclasse.
class Vehicle {
var brand: String
var year: Int
// Initialiseur désigné
init(brand: String, year: Int) {
self.brand = brand
self.year = year
}
}
class Car: Vehicle {
var isElectric: Bool
// Initialiseur désigné
init(brand: String, year: Int, isElectric: Bool) {
self.isElectric = isElectric
super.init(brand: brand, year: year) // Appel à l'initialiseur de la superclasse
}
}
b. Initialiseurs de Commodité (Convenience Initializers)
Les initialiseurs de commodité sont des initialiseurs supplémentaires qui permettent de simplifier la création d'une instance. Ils appellent un autre initialiseur désigné de la même classe pour réaliser une partie ou la totalité de l'initialisation.
class Car {
var brand: String
var year: Int
var isElectric: Bool
// Initialiseur désigné
init(brand: String, year: Int, isElectric: Bool) {
self.brand = brand
self.year = year
self.isElectric = isElectric
}
// Initialiseur de commodité
convenience init(brand: String, isElectric: Bool) {
self.init(brand: brand, year: 2024, isElectric: isElectric)
}
}
let electricCar = Car(brand: "Tesla", isElectric: true)
print("Voiture : \(electricCar.brand), Année : \(electricCar.year), Électrique : \(electricCar.isElectric)")
// Affiche : "Voiture : Tesla, Année : 2024, Électrique : true"
6. Initialisation de Classes Héritées
Lorsqu'une classe hérite d'une autre, les initialiseurs de la classe parente doivent être appelés en premier dans le cadre de l'initialisation de la sous-classe. Cela garantit que toutes les propriétés héritées sont correctement configurées.
class Animal {
var name: String
init(name: String) {
self.name = name
}
}
class Dog: Animal {
var breed: String
init(name: String, breed: String) {
self.breed = breed
super.init(name: name) // Appel à l'initialiseur de la superclasse
}
}
let dog = Dog(name: "Buddy", breed: "Golden Retriever")
print("Nom : \(dog.name), Race : \(dog.breed)") // Affiche : "Nom : Buddy, Race : Golden Retriever"
7. Initialiseurs Requis (Required Initializers)
Les initialiseurs requis sont des initialiseurs qui doivent être implémentés par toutes les sous-classes. Ils sont définis avec le mot-clé required.
class Animal {
var name: String
required init(name: String) {
self.name = name
}
}
class Dog: Animal {
var breed: String
required init(name: String, breed: String) {
self.breed = breed
super.init(name: name)
}
}