在函数签名

时间:2016-08-30 21:54:39

标签: swift polymorphism

我在Swift 2.2和2.3中遇到了一些多态性问题。我正在使用NSManagedObjects并根据具体情况构建视图。我注意到我的视图构建器没有基于模型的子类调用正确的重载函数。

在一个游乐场,我搞砸了一些事情并发现了以下内容:

import Foundation

class DataObject: NSObject {}
class X: DataObject {}
class Y: DataObject {}

class ViewBuilder {
    func viewForModel<S where S: DataObject>(model: S) {
        tmp(model)
    }

    func tmp(model: X) {
        print("X")
    }

    func tmp(model: Y) {
        print("Y")
    }

    func tmp(model: DataObject) {
        print("Base")
    }
}

ViewBuilder().viewForModel(X())

尽管传递了X型,但这打印出“Base”。我错过了什么吗?为什么它调用基类tmp()函数而不是相应子类的函数?

2 个答案:

答案 0 :(得分:1)

这里的子类问题很有趣,但我想知道你是否会因为这样的事情而变得更好:

class ViewBuilder {
    func viewForModel(model: X) {
        print("X")
    }
    func viewForModel(model: Y) {
        print("Y")
    }
    func viewForModel(model: DataObject) {
        print("Base")
    }
}

这产生了预期的结果:

ViewBuilder().viewForModel(X())打印“X”

ViewBuilder().viewForModel(Y())打印“Y”

如果class Z: DataObject {}没有特定方法:

ViewBuilder().viewForModel(Z())打印“Base”

答案 1 :(得分:0)

问题是X首先是DataObject,你必须像这样强制转换为子类:

func viewForModel<S where S: DataObject>(model: S) {
    model.dynamicType
    tmp(model as! X)
}