Swift:如何使Subclass返回类型的函数符合协议,其中Superclass被定义为返回类型?

时间:2016-01-29 22:11:52

标签: swift oop protocols

我有一个协议,其中定义了一个函数,函数的返回类型是SuperclassType

在符合协议的类中,我尝试定义此函数,但返回类型为SubclassType

编译器告诉我,这个类不符合协议,因为显然SubclassType!= SuperclassType

protocol SomeProtocol {
  func someFunction(someParameter:SomeType) -> SuperclassType?
}

class SomeClass : SomeProtocol {
  func someFunction(someParameter:SomeType) -> SubclassType? {
    ...
  }
}

class SubclassType : SuperclassType { }

常识告诉我,SubclassType应该是SuperclassType在此问题上的合适替代。

我做错了什么?

感谢。

1 个答案:

答案 0 :(得分:9)

在您走得更远之前,我建议您在covariance vs contravarianceLiskov substitution principle上阅读一些背景资料。

  • 当子类 协变时,方法重写的返回类型:方法的子类重写可以返回超类的子类型方法的返回类型。

  • 通用类型参数不变:专业化既不能缩小也不能扩展类型要求。

协议和采用它的具体类型之间的关系更像是泛型而不是子类化,因此协议中声明的返回类型也是不变的。 (在第一次阅读时很难确切地说出原因。可能是关于存在主义与仅限制约束的协议吗?)

您可以通过指定关联的类型要求来允许协议中的协方差:

protocol SomeProtocol {
    typealias ReturnType: SuperclassType
    func someFunction(someParameter: SomeType) -> ReturnType
}

class SomeClass : SomeProtocol {
    func someFunction(someParameter: SomeType) -> SubclassType { /*...*/ }
}

现在,很明显,采用someFunction的类型中SomeProtocol的返回类型必须是SuperclassType或其子类型。