2014-07-02 15 views
37

ho la seguente classe, con un metodo init:sottoclassi Swift - come ignorare Init()

class user { 
    var name:String 
    var address:String 

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

Sto cercando di creare una sottoclasse questa classe, ma continuo a ricevere errori da parte 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 di Apple ha esempi di sottoclassi, ma nessuno include classi che hanno un metodo init() con tutti gli argomenti effettivi. Tutti i loro init sono privi di argomenti.

Quindi, come si fa?

+0

Penso che si possa (e si debba) rendere il codice più pulito dichiarando la classe in maiuscolo vero? – Anima

risposta

32

Oltre alla risposta di Chuck, si hanno anche per inizializzare la nuova proprietà introdotto prima di chiamare super.init

Un inizializzatore designato deve garantire che tutte le proprietà introdotte dalla relativa classe vengano inizializzate prima di delegare un inizializzatore della superclasse . (La Swift Programming Language -> Guida linguistica -> inizializzazione)

Così, per farlo funzionare:

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

Questo semplice inizializzazione a zero avrebbe potuto essere fatto impostando il valore predefinito della proprietà anche a zero. E 'anche incoraggiati a farlo:

var numberPriorVisits: Int = 0 

se non si vogliono un tale valore di default che avrebbe senso per estendere la vostra inizializzazione per impostare anche un nuovo valore per la nuova proprietà:

init(name: String, ads: String, numberPriorVisits: Int) { 
    self.numberPriorVisits = numberPriorVisits 
    super.init(nm: name, ad: ads) 
} 
+0

Beh, stavo davvero sperando di * non * di mettere un valore predefinito di 0 a 'numberPriorVisits' - ma stai dicendo che è effettivamente incoraggiato? Puoi condividere dove hai imparato che è incoraggiato? Inoltre, in generale, sto cercando di capire quale sia la migliore pratica quando si tratta di 'init's' in Swift. È meglio dare a tutte le proprietà un valore predefinito e lasciare il tuo metodo init privo di argomenti? O è meglio ** NOT ** avere valori predefiniti e averli tutti fatti passare gli argomenti in 'init'? – sirab333

+0

@sirab: Con incoraggiamento intendo che se si desidera inizializzarlo su un determinato valore, viene incoraggiato il modo di utilizzare un valore predefinito per la proprietà piuttosto che impostare la proprietà su quel valore all'interno dell'inizializzatore. Bene, se la tua soluzione funziona con i valori predefiniti allora non c'è bisogno di parametri di inizializzazione. –

+0

@sirab: ho imparato che è incoraggiato leggendo la guida della lingua. Lo stesso capitolo di cui ho parlato nella mia risposta. Dice "Se una proprietà prende sempre lo stesso valore iniziale, fornisce un valore predefinito anziché impostare un valore all'interno di un inizializzatore. Il risultato finale è lo stesso, ma ..." Leggi e leggi :-) –

3

si passa argomenti per un inizializzatore molto simile si passa argomenti a un metodo normale:

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

Per avere un riferimento, questo viene visualizzato nella sezione Designated and Convenience Initializers In Action della Guida Swift lingua.

0

hai provato ad impostare un valore per numberPriorVisits e cambiare i tipi per le chiamate al 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) 
    } 
} 
11

In swift 2.0 e successive funziona in questo modo (tutti i casi)

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 
} 
Problemi correlati