使一个协议符合另一个协议

Ric*_*hiy 7 protocols ios swift

我有两个协议:PenInstrumentForProfessional。我想使任何一支成为ProfessionalInstrument

protocol Pen {
  var title: String {get}
  var color: UIColor {get}
}

protocol Watch {} // Also Instrument for professional
protocol Tiger {} // Not an instrument

protocol InstrumentForProfessional {
  var title: String {get}
}

class ApplePen: Pen {
  var title: String = "CodePen"
  var color: UIColor = .blue
}

extension Pen: InstrumentForProfessional {} // Unable to make ApplePen an Instument for Professional: Extension of protocol Pen cannot have an inheritance clause

let pen = ApplePen() as InstrumentForProfessional
Run Code Online (Sandbox Code Playgroud)

use*_*434 18

协议可以相互继承

协议继承

一个协议可以继承一个或多个其他协议,并且可以在它继承的需求之上添加更多的需求。协议继承的语法类似于类继承的语法,但可以选择列出多个继承的协议,用逗号分隔:

protocol InheritingProtocol: SomeProtocol, AnotherProtocol {
    // protocol definition goes here
}
Run Code Online (Sandbox Code Playgroud)

所以,你基本上需要这样做:

protocol InstrumentForProfessional {
    var title: String {get}
}

protocol Pen: InstrumentForProfessional {
    var title: String {get} // You can even drop this requirement, because it's already required by `InstrumentForProfessional`
    var color: UIColor {get}
}
Run Code Online (Sandbox Code Playgroud)

现在一切符合的也Pen符合InstrumentForProfessional

  • 是的,但是 OP 正在使用扩展。 (5认同)
  • 感谢您的建议,但@user28434 您居高临下的语气不受欢迎。让我们彼此友好 (4认同)
  • @paper1111,*那又怎样*?**他正在展示他尝试过的方法,但不起作用。**并且他特别要求能够使所有“Pen”也成为“InstrumentForProfessional”。这就是我的答案的作用。 (2认同)

pap*_*111 7

这是您要求符合扩展协议的方式。

extension Pen where Self: InstrumentForProfessional {}
Run Code Online (Sandbox Code Playgroud)

当前的操作方式使编译器认为您正在进行继承,而不是协议一致性。

还要注意,let pen = ApplePen() as InstrumentForProfessional这没有意义,也不会编译。

  • @paper1111,不,不是。你的扩展只允许指定一些代码,所有符合 `Pen` 和 `InstrumentForProfessional` 的类型都将拥有,而不是所有符合 `Pen` 的类型都符合 `InstrumentForProfessional`。并且将类型的值转换为类型符合的协议是有效的构造(假设协议没有关联的类型)。 (2认同)