La délégation d'initialisation est un système de délégation d'initialisation intégré dans Swift pour les classes. En Swift, il existe historiquement une distinction entre l'initialisateur désigné (l'initialisateur principal de la classe, responsable de l'initialisation complète de toutes les propriétés) et l'initialisateur de commodité (un initialisateur auxiliaire qui facilite la création d'instances avec différents ensembles de paramètres).
Problème : si les initialisateurs sont exécutés de manière chaotique entre les classes et leurs héritiers, il est possible que la classe de base ne soit pas entièrement initialisée, ou que l'initialisation se produise plus d'une fois, ce qui entraînera un objet invalide.
Solution — règle stricte :
Exemple de code :
class Vehicle { var wheels: Int // Initialisateur désigné init(wheels: Int) { self.wheels = wheels } // Initialisateur de commodité convenience init() { self.init(wheels: 4) } } class Car: Vehicle { var color: String // Initialisateur désigné init(wheels: Int, color: String) { self.color = color super.init(wheels: wheels) } // Initialisateur de commodité convenience init(color: String) { self.init(wheels: 4, color: color) } }
Caractéristiques clés :
Question 1 : Un initialisateur de commodité peut-il appeler directement l'initialisateur de la superclasse via super.init ?
Non, l'initialisateur de commodité délègue toujours l'initialisation à un autre initialisateur de la même classe, qui peut ensuite appeler l'initialisateur désigné de la superclasse.
Question 2 : Que se passe-t-il si l'initialisateur requis n'est pas implémenté dans la sous-classe ?
Si la superclasse a un initialisateur requis, il doit obligatoirement être redéfini dans chaque sous-classe (en utilisant required), sinon le compilateur renverra une erreur.
Question 3 : Quelle est la différence entre convenience init et convenience required init ?
convenience required init est nécessaire si un initialisateur de commodité spécifique est déclaré comme requis dans la superclasse pour assurer le support de l'initialisation dans les hiérarchies d'héritage.
Un développeur a appelé super.init depuis l'initialisateur de commodité. Le code a été compilé uniquement grâce à l'absence de certaines restrictions, mais au moment de l'exécution, une erreur s'est produite : toutes les propriétés de l'objet n'étaient pas initialisées.
Avantages :
Inconvénients :
Des initialisateurs désignés et de commodité clairement structurés ont été utilisés avec des appels explicites l'un à l'autre. La logique était appelée strictement selon les règles de Swift, garantissant ainsi une initialisation toujours transparente et correcte.
Avantages :
Inconvénients :