Swift Protocol Extensions overriding

The short answer is that protocol extensions don’t do class polymorphism. This makes a certain sense, because a protocol can be adopted by a struct or enum, and because we wouldn’t want the mere adoption of a protocol to introduce dynamic dispatch where it isn’t necessary.

Thus, in getColor(), the color instance variable (which may be more accurately written as self.color) doesn’t mean what you think it does, because you are thinking class-polymorphically and the protocol is not. So this works:

let colorB = B().color // is "Red color" - OK

…because you are asking a class to resolve color, but this doesn’t do what you expect:

let b = B().getColor() // is "Default color" BUT I want it to be "Red color"

…because the getColor method is defined entirely in a protocol extension. You can fix the problem by redefining getColor in B:

class B: A, RedColor {
    func getColor() -> String {
        return self.color
    }
}

Now the class’s getColor is called, and it has a polymorphic idea of what self is.

Leave a Comment