Skip to content

Instantly share code, notes, and snippets.

@AliSoftware
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AliSoftware/24abac9d47505c9d7546 to your computer and use it in GitHub Desktop.
Save AliSoftware/24abac9d47505c9d7546 to your computer and use it in GitHub Desktop.
# Swift 2.0
protocol AbstractAnimal : CustomStringConvertible {
// Abstract, to implement
var firstName: String { get set }
var lastName: String { get set }
// var fullName: String { get } // don't declare it this time!
}
/*:
**Important**: We **don't** declare fullName in the protocol
So that's the Protocol itself that has an implementation and we can call
this implementation if we cast an object to that Protocol
*/
//: Provide a protocol implementation for fullName
//: and a default implementation for description
extension AbstractAnimal {
var fullName: String {
return "\(firstName) \(lastName)"
}
var description: String {
return "\(self.dynamicType): \(fullName)"
}
}
struct ConcreteDog : AbstractAnimal {
var firstName: String
var lastName: String
}
ConcreteDog(firstName: "Droopy", lastName: "Dog")
struct ConcreteCat : AbstractAnimal {
var firstName: String
var lastName: String
var fullName: String {
return "Mr Cat \(firstName) the \(lastName)"
}
}
let felix = ConcreteCat(firstName: "Felix", lastName: "Cat")
//: Call the specific implementation
felix.fullName // -> "Mr Cat Felix the Cat"
//: Call the protocol's own implementation
(felix as AbstractAnimal).fullName // -> "Felix Cat"
//: Call the specific description… which should use the specific fullName, right? Oh, no, but why?!
felix.description // -> "ConcreteCat: Felix Cat" (and NOT "ConcreteCat: Mr Cat Felix the Cat")
//: In fact it's the same as this
(felix as AbstractAnimal).description // -> "ConcreteCat: Felix Cat" (same as above)
// Of course, if I copy/paste `AbstractAnimal`'s `description` implementation in `ConcreteCat`'s implementation then it works as expected
//
// To my understanding, that demonstrates that, because felix.description uses static dispatch, it won't dynamically dispatch the internal
// call to fullName either (leading to unexpected and unnatural behavior)
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment