Swift - How can I override an extension method in a concrete subclass Swift - How can I override an extension method in a concrete subclass swift swift

Swift - How can I override an extension method in a concrete subclass


As others have noted, Swift does not (yet) allow you to override a method declared in a class extension. However, I'm not sure whether you'll ever get the behavior you want even if/when Swift someday allows you to override these methods.

Consider how Swift deals with protocols and protocol extensions. Given a protocol to print some metasyntactic variable names:

protocol Metasyntactic {    func foo() -> String    func bar() -> String}

An extension to provide default implementations:

extension Metasyntactic {    func foo() -> String {        return "foo"    }    func bar() -> String {        return "bar"    }}

And a class that conforms to the protocol:

class FooBar : Metasyntactic {    func foo() -> String {        return "FOO"    }    func bar() -> String {        return "BAR"    }}

Swift will use dynamic dispatch to call the appropriate implementations of foo() and bar() based on each variable's runtime type rather than on the type inferred by the compiler:

let a = FooBar()a.foo()  // Prints "FOO"a.bar()  // Prints "BAR"let b: Metasyntactic = FooBar()b.foo()  // Prints "FOO"b.bar()  // Prints "BAR"

If, however, we extend the protocol further to add a new method:

extension Metasyntactic {    func baz() -> String {        return "baz"    }}

And if we override our new method in a class that conforms to the protocol:

class FooBarBaz : Metasyntactic {    func foo() -> String {        return "FOO"    }    func bar() -> String {        return "BAR"    }    func baz() -> String {        return "BAZ"    }}

Swift will now use static dispatch to call the appropriate implementation of baz() based on the type inferred by the compiler:

let a = FooBarBaz()a.baz()  // Prints "BAZ"let b: Metasyntactic = FooBarBaz()b.baz()  // Prints "baz"

Alexandros Salazar has a fantastic blog post explaining this behavior in depth, but suffice it to say that Swift only uses dynamic dispatch for methods declared in the original protocol, not for methods declared in protocol extensions. I imagine the same would be true of class extensions, as well.


I know this question has been asked a while ago. But this will be handy for someone who looking for an easier way. There is a way of overriding an extension methods. I know its bit hacky but it does the job beautifully.

If you declare your protocol with @objc

@objc protocol MethodOverridable {   func overrideMe()}

In Extension

extension MainClass: MethodOverridable {     func overrideMe() {        print("Something useful")     } }

Subclass - You can able to override it in your subclass. It works like a magic. Well, not really when adding @objc it exposes your protocol to Objective-C and its Runtime. That allows your subclass to override.

 class SubClass: MainClass {     override func overrideMe() {          print("Something more useful")      }    }


It looks like you can override property for 2nd super class property. For example, you can access UIView property by making extension to the UILabel wanting to override frame property of UIView. This sample works for me in Xcode 6.3.2

extension UILabel {     override public var frame: CGRect {         didSet {             println("\(frame)")        }     }}