Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple protocol inheritance in Swift 2.0 using extension protocols [duplicate]

Tags:

swift

swift2

Given the two protocols and their extensions:

protocol FirstDelegate {
    func someFunc()
}

protocol SecondDelegate {
    func someFunc()
}

extension FirstDelegate {
    func someFunc() {
        print("First delegate")
    }
}

extension SecondDelegate {
    func someFunc() {
        print("Second delegate")
    }
}

and trying to conform to both of them:

class SomeClass: FirstDelegate, SecondDelegate {}

I receive compile-time error:

Type 'SomeClass' does not conform to protocol 'FirstDelegate'

Exchanging FirstDelegate and SecondDelegate:

class SomeClass: SecondDelegate, FirstDelegate {}

produces reverse:

Type 'SomeClass' does not conform to protocol 'SecondDelegate'

Removing one of the extensions resolves the problem. Ditto providing implementation for someFunc() inside SomeClass.

This protocol extension functionality is rather new to me. Also the information about it in an Apple's official 'Swift Programming Guide (Prerelease)' is scarce at the moment.

Did I violate some rules of protocol extensions here?

like image 679
mesmerizingr Avatar asked Jul 23 '15 12:07

mesmerizingr


People also ask

Can a protocol inherit from another protocol Swift?

A Swift protocol can inherit from other protocols, requiring conforming types to provide implementations for all the property and method requirements in the entire protocol hierarchy. A protocol can inherit from multiple protocols by listing the parent protocols in its declaration, separated by commas.

How does Swift achieve multiple inheritance?

Swift does not support multiple inheritance. That is, you cannot inherit from more than one class.

Can protocols inherit other protocols?

One protocol can inherit from another in a process known as protocol inheritance. Unlike with classes, you can inherit from multiple protocols at the same time before you add your own customizations on top.

Can a protocol extend a protocol Swift?

In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions. Extensions can add new functionality to a type, but they can't override existing functionality.


1 Answers

A protocol defines requirements (methods, properties, ...) for a conformant type.

protocol FirstDelegate {
    func someFunc()
}

protocol SecondDelegate {
    func someFunc()
}

defines two protocols with the same required method someFunc(). A conformant type must implement this method:

class SomeClass: FirstDelegate, SecondDelegate {
    func someFunc() {
        print("SomeClass implementation")
    }
}

A protocol extension provides method and property implementations to conformant types. A special case of a protocol extension is a default implementation, which is what you defined here:

extension FirstDelegate {
    func someFunc() {
        print("First delegate")
    }
}

It defines a default implementation of someFunc() for all types conforming to FirstDelegate. Since this is the only required method of that protocol, a conforming class need not define the method at all:

class SomeClass: FirstDelegate {

}

SomeClass().someFunc() // Output: First delegate

But if the class provides its own implementation then that will be used:

class SomeClass: FirstDelegate {
    func someFunc() {
        print("SomeClass implementation")
    }
}

SomeClass().someFunc() // Output: SomeClass implementation

In your case, you have defined default implementations of someFunc() for both protocols:

extension FirstDelegate {
    func someFunc() {
        print("First delegate")
    }
}

extension SecondDelegate {
    func someFunc() {
        print("Second delegate")
    }
}

A class can still conform to both protocols if it provides its own implementation of the required method:

class SomeClass: FirstDelegate, SecondDelegate {
    func someFunc() {
        print("SomeClass implementation")
    }
}

But the class cannot conform by using the default implementation

class SomeClass: FirstDelegate, SecondDelegate {

}

for both protocols because there is a conflict. It is unspecified which default implementation should be used, and that's why the compiler complains.

Actually the class now conforms to none of the protocols. This can be seen in the full compiler log in the Report navigator:

main.swift:24:7: error: type 'SomeClass' does not conform to protocol 'FirstDelegate'
class SomeClass: FirstDelegate, SecondDelegate {
      ^
main.swift:5:10: note: multiple matching functions named 'someFunc()' with type '() -> ()'
    func someFunc()
         ^
main.swift:19:10: note: candidate exactly matches
    func someFunc() {
         ^
main.swift:13:10: note: candidate exactly matches
    func someFunc() {
         ^
main.swift:24:7: error: type 'SomeClass' does not conform to protocol 'SecondDelegate'
class SomeClass: FirstDelegate, SecondDelegate {
      ^
main.swift:9:10: note: multiple matching functions named 'someFunc()' with type '() -> ()'
    func someFunc()
         ^
main.swift:19:10: note: candidate exactly matches
    func someFunc() {
         ^
main.swift:13:10: note: candidate exactly matches
    func someFunc() {
         ^
like image 148
Martin R Avatar answered Oct 19 '22 00:10

Martin R