web-dev-qa-db-fra.com

Sous-classement rapide - comment redéfinir Init ()

J'ai la classe suivante, avec une méthode init:

class user {
  var name:String
  var address:String

  init(nm: String, ad: String) {
    name = nm
    address = ad
  }
}

J'essaie de sous-classer cette classe mais je continue à avoir des erreurs sur la partie super.init():

class registeredUser : user {
     var numberPriorVisits: Int

     // This is where things start to go wrong - as soon as I type 'init' it 
     // wants to autocomplete it for me with all of the superclass' arguments, 
     // and I'm not sure if those should go in there or not:
     init(nm: String, ad: String) {  
        // And here I get errors:
        super.init(nm: String, ad: String) 

     // etc....

L'iBook d'Apple contient des exemples de sous-classes, mais aucune des classes d'entités comportant une méthode init() avec des arguments réels. Tous leurs init sont dépourvus d'arguments.

Alors coment faites-vous cela?

39
sirab333

En plus de la réponse de Chuck, vous devez également initialiser votre nouvelle propriété introduite avant d'appeler super.init

Un initialiseur désigné doit s'assurer que toutes les propriétés introduits par sa classe sont initialisés avant qu'il ne délègue un initialiseur de superclasse. (Le langage de programmation Swift -> Guide de la langue -> Initialisation)

Ainsi, pour le faire fonctionner:

init(nm: String, ad: String) {
    numberPriorVisits = 0  
    super.init(nm: nm, ad: ad) 
}

Cette initialisation simple à zéro aurait pu être effectuée en définissant également la valeur par défaut de la propriété sur zéro. Il est également encouragé de le faire:

var numberPriorVisits: Int = 0

Si vous ne voulez pas d'une telle valeur par défaut, il serait judicieux d'étendre votre initialiseur afin de définir également une nouvelle valeur pour la nouvelle propriété:

init(name: String, ads: String, numberPriorVisits: Int) {
    self.numberPriorVisits = numberPriorVisits
    super.init(nm: name, ad: ads)
}
34
Jens Wirth

Dans Swift 2.0 et versions ultérieures, cela fonctionne comme suit (tous les cas)

init(newString:String) {
    super.init(string:newString)
    // Designed initialiser 
}
override init(someString: String) {
    super.init(mainString: someString)
    // Override initialiser when subclass some class 
}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
    // Some boilerplate code to handle error (needed when override)
}
convenience init(newString:String, withParameters:Dictionary<String,String>) {
    self.init(someString:newString)
    //Convenience initialiser 
}
11
Roman Safin

Vous transmettez des arguments à un initialiseur de la même manière que vous transmettez des arguments à une méthode normale:

init(nm: String, ad: String) {  
    super.init(nm: nm, ad: ad) 
}

À titre de référence, cela apparaît dans la section Initiateurs désignés et pratiques en action du Guide de la langue rapide.

3
Chuck

Avez-vous essayé de définir une valeur sur numberPriorVisits et de changer les types d'appels en super

class user {
    var name:String
    var address:String

    init(nm: String, ad: String) {
        name = nm
        address = ad
    }
}


class registeredUser : user {
    var numberPriorVisits: Int;

    init(nm: String, ad: String) {
        self.numberPriorVisits = 0;
        super.init(nm: nm, ad: ad)
    }
}
0
Peter Witham