Swift,我可以使用更具体的派生参数类型覆盖方法

时间:2015-07-25 17:47:30

标签: swift overloading override ios8.3

PlayingCard继承自卡

给出两个具有相同名称的函数:

 func match(othercards : [PlayingCard]) ->  Int {
     return 2 
 }

 func match(othercards : [Card]) ->  Int {
     return 2 
 }

抛出一个错误说:覆盖方法与选择器'匹配:'具有不兼容的类型'([PlayingCard]) - > Int'

为什么???它的两个函数具有相同的名称但两种不同的参数为什么它仍然要求覆盖?如果我这样做,那么即使这被称为错误

3 个答案:

答案 0 :(得分:2)

你能这样做吗?

class Card {
    func match(othercards : [Card]) ->  Int {
        return 2 // I changed the return value just to test it
    }
}

class PlayingCard : Card {
    func match(othercards : [PlayingCard]) ->  Int {
        return 1
    }
}

是!

具体而言,如果卡不延伸NSObject ,则可以。

class Card {
    func match(othercards : [Card]) ->  Int {
        return 2 // I changed the return value just to test it
    }
}

另一方面,如果Card延伸NSObject

class Card : NSObject {
    func match(othercards : [Card]) ->  Int {
        return 2 // I changed the return value just to test it
    }
}

然后你得到错误!

看起来overloading仅适用于"纯粹的" Swift课程。

答案 1 :(得分:1)

Swift编译器必须同时将PlayingCardCard视为同一类型。如果一个人继承(通过子类型或协议(在某些情况下)),这可以解释它。

虽然可以将其视为code smell,但您也可以在运行时检查类型,并且只使用一个函数,如此处接受的答案:Checking if an object is a given type in Swift

可以应用的一些模式在类似示例的解释中给出 - 尽管问题是关于C#,但可以应用类似的面向对象技术:overriding method with derived parameter instead of base

答案 2 :(得分:0)

由于PlaingCard继承自Card,因此不允许以这种方式覆盖该方法。

考虑如果您尝试使用PlayingCard实例调用匹配会发生什么。它会调用哪两种方法?这将是模棱两可的,因此是不允许的。

在这种情况下,一种解决方案是更改采用更具体类型的方法的名称。 e.g。

 func matchPlayingCard(othercards : [PlayingCard]) ->  Int {
     return 2 
 }