Last active
August 29, 2015 14:23
-
-
Save AliSoftware/24abac9d47505c9d7546 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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