Skip to content

Instantly share code, notes, and snippets.

@robertmryan
Last active January 23, 2017 06:35
Show Gist options
  • Select an option

  • Save robertmryan/671b7645d925d80b1eba41c6864f004e to your computer and use it in GitHub Desktop.

Select an option

Save robertmryan/671b7645d925d80b1eba41c6864f004e to your computer and use it in GitHub Desktop.
Swift protocol default implementation idiosyncrasy
// note, P does not declare `greet` as requirement
protocol P {}
// ... but this does provide a "default" implementation
extension P {
func greet() {print("hello")}
}
// ... so if you have a class that overrides this
class C : P {
func greet() {print("hello from C")}
}
// ... but then use the protocol, rather than the class
func greeter(_ obj: P) {
obj.greet()
}
// then this will, confusingly IMHO, print "hello", not "hello from C"
greeter(C())
// ----
// However, if we define a protocol with this as a requirement
protocol Q {
func greet()
}
// ... and provide a default implementation
extension Q {
func greet() {print("hello")}
}
// ... and then override this default implementation
class D : Q {
func greet() {print("hello from D")}
}
// ... now this Q will honor any overrides that the class may implement
func anotherGreeter(_ obj: Q) {
obj.greet()
}
// ... this will now print "hello from D", as you'd expect it to
anotherGreeter(D())
@robertmryan

Copy link
Copy Markdown
Author

See my cautionary comment at http://stackoverflow.com/a/41797095/1271826

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment