Kurt Horimoto
Kurt Horimoto

Reputation: 99

Default Swift protocol implementation in extension for class that conforms to other protocol

I have a class where some subclasses conform to Protocol1. The API from Protocol1 is sufficient to implement Protocol2. I want to do something like below, where I can define a default implementation of Protocol2 when an instance of my class conforms to Protocol1. My first attempt looks like this:

public class MyClass {}

public protocol Protocol1 {
  var someProperty: Any { get }
}

public protocol Protocol2 {
  var func someFunc()
}

extension Protocol2 where Self: MyClass & Protocol1 {
  public func someFunc() {
    // Functionality that uses `.someProperty`
  } 
}

This compiles fine, so I thought it would work. However I tried testing with something like:

public class MySubclass: MyClass {}
extension MySubclass: Protocol1 {
  public var someProperty: Any {
    // Return property value.
  }
}

let instance = MySubclass()
instance.someFunc()  // Throws compilation error

Unfortunately, I get a Value of type 'MySubclass' has no member 'someFunc' compilation error when attempting to call the function from Protocol2. Is there a way to define a default implementation of Protocol2 for MyClass subclasses conforming to Protocol1, or would I just need to extend each subclass individually?

Upvotes: 1

Views: 1679

Answers (1)

Kurt Horimoto
Kurt Horimoto

Reputation: 99

Figured it out actually. You can define the default implementation with the where clause, but you still need to explicitly conform to Protocol2. I have several MyClass subclasses conforming to Protocol1, so I didn't want to duplicate the implementations, but just adding explicit protocol conformance to Protocol2 with an empty definition block works:

extension Protocol2 where Self: MyClass & Protocol1 {
  public func someFunc() {
    // Functionality that uses `.someProperty`
  } 
}

public class MySubclass: MyClass {}
extension MySubclass: Protocol1 {
  public var someProperty: Any {
    // Return property value.
  }
}
extension MySubclass: Protocol2 {}

MySubclass().someFunc() // Works fine

Upvotes: 0

Related Questions