欢迎加入QQ讨论群258996829
hongyin 头像
苹果0袋
0
hongyin

求助:failable initializer 'init(name:)' cannot override a non-failable initializer

发布时间:2015-10-08 10:51  回复:13  查看:18762   最后回复:2015-10-10 11:16  
各位,有谁知道 failable initializer 'init(name:)' cannot override a non-failable initializer,这句背后的道理的吗?最好详细一些。  
一叶知秋 头像
苹果2袋
2
一叶知秋   2015-10-08 11:13
怎么产生这个错误的呀。
一叶知秋 头像
苹果2袋
2
一叶知秋   2015-10-08 11:27
字面上看是重写init方法时出错
hongyin 头像
苹果0袋
0
hongyin   2015-10-08 14:32

是的是重写init方法时出错,我就是想知道 failable initializer  为什么不能用 non-bailable initializer来重写。例子:

class Document {

    var name: String?

    // this initializer creates a document with a nil name value

    init() {}

    // this initializer creates a document with a non-empty name value

    init(name: String) {

        self.name = name

    }

}


class AutomaticallyNamedDocument: Document {

    override init() {

        super.init()

        self.name = "[Untitled]"

    }

    // This is nonfailable override superclass's failable

    override init?(name: String) {

        // Why subclass initializer still can delegate up to the superclass initializer??

        super.init(name:name)

        if name.isEmpty { return nil }

    }

}


出错在override init?(name: String) 一行。


error: failable initializer 'init(name:)' cannot override a non-failable initializer

    override init?(name: String) {

             ^

/var/folders/mh/10bq32_x1rg7dwzkycm931q80000gn/T/./lldb/4797/playground29.swift:15:5: note: non-failable initializer 'init(name:)' overridden here

    init(name: String) {

    ^

为啥不能重写呢?我想知道背后的原因。



赢了现在输了未来 头像
苹果2袋
2
赢了现在输了未来   2015-10-08 16:36

把init后的?号去掉

override init(name: String) {

    super.init(name:name)

    if name.isEmpty { return nil }

}

hongyin 头像
苹果0袋
0
hongyin   2015-10-08 16:50
@赢了现在输了未来

把init后的?号去掉

override init(name: String) {

    super.init(name:name)

    if name.isEmpty { return nil }

}

嗯,是的,但是我想知道为什么有这个限制呢?
赢了现在输了未来 头像
苹果2袋
2
赢了现在输了未来   2015-10-08 16:55
@hongyin
@赢了现在输了未来

把init后的?号去掉

override init(name: String) {

    super.init(name:name)

    if name.isEmpty { return nil }

}

嗯,是的,但是我想知道为什么有这个限制呢?

是重写的话,应该是要和父类的方法完全一致,否则怎么叫重写呢。

hongyin 头像
苹果0袋
0
hongyin   2015-10-08 16:59
如果 父类的 

init(name: String) {...}

变成 

init?(name: String) { ... }

子类重写成

init(name: String) {...}

就可以,为什么反过来就不行了呢?


赢了现在输了未来 头像
苹果2袋
2
赢了现在输了未来   2015-10-08 17:05
@hongyin
如果 父类的 

init(name: String) {...}

变成 

init?(name: String) { ... }

子类重写成

init(name: String) {...}

就可以,为什么反过来就不行了呢?


这样啊,值得深思。
hongyin 头像
苹果0袋
0
hongyin   2015-10-08 17:06
@赢了现在输了未来
@hongyin
如果 父类的 

init(name: String) {...}

变成 

init?(name: String) { ... }

子类重写成

init(name: String) {...}

就可以,为什么反过来就不行了呢?


这样啊,值得深思。

是的,所以我很郁闷呢。我的QQ : 26743552 ,可以加一个吗,讨论一下。

赢了现在输了未来 头像
苹果2袋
2
赢了现在输了未来   2015-10-08 17:11
@hongyin
@赢了现在输了未来
@hongyin
如果 父类的 

init(name: String) {...}

变成 

init?(name: String) { ... }

子类重写成

init(name: String) {...}

就可以,为什么反过来就不行了呢?


这样啊,值得深思。

是的,所以我很郁闷呢。我的QQ : 26743552 ,可以加一个吗,讨论一下。

可以,晚点加你。
Swift 头像
苹果5袋
5
Swift   2015-10-08 21:51

SWIFT2.0的翻译文档里做了如下说明


重写一个可失败构造器


就如同其它构造器一样,你也可以用子类的可失败构造器重写基类的可失败构造器。或者你也可以用子类的非可失败构造器重写一个基类的可失败构造器。这样做的好处是,即使基类的构造器为可失败构造器,但当子类的构造器在构造过程不可能失败时,我们也可以把它修改过来。

注意当你用一个子类的非可失败构造器重写了一个父类的可失败构造器时,子类的构造器将不再能向上代理父类的可失败构造器。一个非可失败的构造器永远也不能代理调用一个可失败构造器。


注意: 你可以用一个非可失败构造器重写一个可失败构造器,但反过来却行不通。

hongyin 头像
苹果0袋
0
hongyin   2015-10-08 22:34
@Swift

SWIFT2.0的翻译文档里做了如下说明


重写一个可失败构造器


就如同其它构造器一样,你也可以用子类的可失败构造器重写基类的可失败构造器。或者你也可以用子类的非可失败构造器重写一个基类的可失败构造器。这样做的好处是,即使基类的构造器为可失败构造器,但当子类的构造器在构造过程不可能失败时,我们也可以把它修改过来。

注意当你用一个子类的非可失败构造器重写了一个父类的可失败构造器时,子类的构造器将不再能向上代理父类的可失败构造器。一个非可失败的构造器永远也不能代理调用一个可失败构造器。


注意: 你可以用一个非可失败构造器重写一个可失败构造器,但反过来却行不通。

注意: 你可以用一个非可失败构造器重写一个可失败构造器,但反过来却行不通。 反过来有什么不可以的呢?能给解释一下吗?
一叶知秋 头像
苹果2袋
2
一叶知秋   2015-10-10 11:16
楼主真打破砂锅问到底啊,钻研精神可嘉,不过这个背后的道理估计没人知道,swift2才出来没多久。
您还未登录,请先登录

热门帖子

最新帖子