How to override swift protocol functions for subclasses (e.g. UILabel from UIView)

You can achieve that as below, You just need to expose aProtocol to Objective-c runtime for overriding its methods in the extension.

@objc protocol aProtocol {
    typealias completionBlock = (_ finished:Bool)->()
    func doSomething(completion: completionBlock)
}

extension UIView: aProtocol {
    func doSomething(completion: (Bool) -> ()) {
        print("Im an UIView")
    }
}

extension UILabel {
    override func doSomething(completion: (Bool) -> ()) {
        // you can call super.doSomething(completion: completion)
        print("im an UILabel")
    }
}

extension UIImageView {
    override func doSomething(completion: (Bool) -> ()) {
        // you can call super.doSomething(completion: completion)
        print("im an UIImageView")
    }
}

Output:

Im an UIView
Im an UIView
im an UILabel
im an UIImageView

- The answer

concrete type conforming to a protocol will used over the protocol constraint. So by changing this:

extension UIView: aProtocol {
    func doSomething(completion: (Bool) -> ()) {
        print("Im an UIView")
    }
}

to this:

extension aProtocol where Self: UIView {
    func doSomething(completion: (Bool) -> ()) {
        print("im an UIView")
    }
}

extension UIView: aProtocol {}

Your code will work as you expect.

- The alternative

You can achieve all of your desired prints with this:

extension aProtocol {
    func doSomething(completion: completionBlock) {
        print("im a \(type(of: self))")
    }
}

extension UIView: aProtocol {}

This means you can check the actual type of the object right inside the protocol extension.

- The explanation

Protocol extensions doesn't override any method. In fact, they are just default implementation if the actual concrete type doesn't implement it.

And protocol constraint defines witch type can infer it's default implementation. So:

extension aProtocol where Self: UILabel

means any subcalss of UILabel that is conformed to aProtocol and does not implement the requirements should infer de default implementation. So this will work only if UILabel conforms to aProtocol directly:

extension UILabel: aProtocol {}

or if it's supercalss conforms to it:

extension UIView: aProtocol {}