Swift subclassing - how to override Init()

a 夏天 提交于 2019-12-03 08:58:22

问题


I have the following class, with an init method:

class user {
  var name:String
  var address:String

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

I'm trying to subclass this class but I keep getting errors on the super.init() part:

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....

Apple's iBook has examples of subclassing, but none those feature classes that have an init() method with any actual arguments in it. All their init's are devoid of arguments.

So, how do you do this?


回答1:


In addition to Chuck's answer, you also have to initialize your new introduced property before calling super.init

A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer. (The Swift Programming Language -> Language Guide -> Initialization)

Thus, to make it work:

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

This simple initialization to zero could have been done by setting the property's default value to zero too. It's also encouraged to do so:

var numberPriorVisits: Int = 0

If you don't want such a default value it would make sense to extend your initializer to also set a new value for the new property:

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



回答2:


In swift 2.0 and Later it works like this (all cases)

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 
}



回答3:


You pass arguments to an initializer much like you pass arguments to a normal method:

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

For reference, this is shown in the Designated and Convenience Initializers In Action section of the Swift Language Guide.




回答4:


Have you tried setting a value to numberPriorVisits and changing the types for the calls to 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)
    }
}


来源:https://stackoverflow.com/questions/24521876/swift-subclassing-how-to-override-init

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!