简体   繁体   English

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

[英]Swift: How can I make a function with a Subclass return type conform to a protocol, where a Superclass is defined as a return type?

I have a protocol, where a function is defined, the return type of a function is a SuperclassType .我有一个协议,其中定义了一个函数,函数的返回类型是SuperclassType

In a class which conforms to the protocol I'm trying to define this function, but with a SubclassType return type.在符合协议的类中,我试图定义此函数,但具有SubclassType返回类型。

Compiler tells me, that this class does not conform to the protocol, because obviously SubclassType != SuperclassType编译器告诉我,这个类不符合协议,因为显然SubclassType != SuperclassType

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

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

class SubclassType : SuperclassType { }

Common sense tells me, though, that SubclassType should be a suitable substitute for a SuperclassType in this matter.不过,常识告诉我,在这件事上, SubclassType应该是SuperclassType的合适替代品。

What am I doing wrong?我究竟做错了什么?

Thanks.谢谢。

Before you go much further, I'd recommend some background reading on covariance vs contravariance and the Liskov substitution principle .在你更进一步之前,我建议你阅读一些关于协变与逆变Liskov 替换原则的背景阅读。

  • Return types for methods overridden when subclassing are covariant : the subclass override of a method can return a subtype of the superclass method's return type.子类化协变覆盖的方法的返回类型:方法的子类覆盖可以返回超类方法的返回类型的类型。

  • Generic type parameters are invariant : a specialization can neither narrow nor expand the type requirements.泛型类型参数是不变的:特化既不能缩小也不能扩展类型要求。

The relationship between a protocol and a concrete type that adopts it is more like generics than like subclassing, so return types declared in protocols are invariant, too.协议和采用它的具体类型之间的关系更像是泛型而不是子类化,因此协议中声明的返回类型也是不变的。 (It's hard to say exactly why on first read. Possibly something about existential vs constraint-only protocols?) (很难在第一次阅读时确切说出原因。可能是关于存在与仅约束协议的内容?)

You can allow covariance in a protocol by specifying associated type requirements, though:您可以通过指定关联的类型要求来允许协议中的协变,但是:

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

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

Now, it's clear that the return type of someFunction in a type adopting SomeProtocol must be either SuperclassType or a subtype thereof.现在,很明显,采用SomeProtocol类型中someFunction的返回类型必须是SuperclassType或其子类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM