1

I have given the some default implementation code in protocol extension. But how to call this specified code in a class that confirms to the protocol. Here is an example:

class BaseClass {}
protocol ImplementedProtocol {
    func printInfo()
}
extension ImplementedProtocol where Self: BaseClass {
    func printInfo() {
        print("Hello! This is ImplementedProtocol")
    }
}

class SuperClass: BaseClass, ImplementedProtocol {
    func printInfo() {
        // I should do sth here.
        print("Hello! This is SuperClass")
    }
}
class SubClass: SuperClass {
    override func printInfo() {
        super.printInfo()
        print("This is SubClass")
    }

}

let a = SubClass()
a.printInfo() // I get "Here is SuperClass. Here is SubClass."
// But I want "Here is ImplementedProtocol. Here is SuperClass. Here is SubClass."
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Vitreous-Flower
  • 257
  • 3
  • 18
  • 1
    I believe [this question](http://stackoverflow.com/questions/32602712/calling-protocol-default-implementation-from-regular-method) might help you. – Paulo Mattos Apr 01 '17 at 15:50
  • 2
    Well, when I try to use code like `(self as ImplementedProtocol).printInfo()` in SuperClass, it just calls the `printInfo()` in SubClass. It causes a infinite loop. – Vitreous-Flower Apr 01 '17 at 16:09

1 Answers1

6

A protocol is more like a compile-time guarantee that type has certain methods and properties. Default implementation adds another layer of complexity to this by injecting an implementation to the protocol's adopters. I don't have the skills to go through Swift's source code but I think when the adopter provide its own implementation, the default implementation is overshadowed and there's no way to get it back.

A workaround is to add a method with a different name to your protocol, which provides the default implementation and can be called by any adopter:

protocol ImplementedProtocol {
    func printInfo()

    func defaultPrintInfo()
}

extension ImplementedProtocol where Self: BaseClass {
    func printInfo() {
        defaultPrintInfo()
    }

    func defaultPrintInfo() {
        print("Hello! This is ImplementedProtocol")
    }
}

class SuperClass: BaseClass, ImplementedProtocol {
    func printInfo() {
        self.defaultPrintInfo()
        print("Hello! This is SuperClass")
    }
}
Mike Henderson
  • 2,028
  • 1
  • 13
  • 32
  • Since my idea is not a preferred code style in swift, I had decided to move the implementation from `ImplementedProtocol ` to `SuperClass `, though I have to implement the similar code for classes inherited from `ImplementedProtocol `. Thanks for your answer. – Vitreous-Flower Apr 01 '17 at 17:05