Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialDavid Keck
5,723 PointsWhy isn't anotherUser using the PersonType extension fullName function?
I'm having trouble understanding how anotherUser picks which function to use. For some reason anotherUser calls the struct User version of fullName, while using the PersonType extension version of greeting.
protocol PersonType {
var firstName: String { get }
var middleName: String? { get }
var lastName: String { get }
func fullName() -> String
}
extension PersonType {
func fullName() -> String {
return "\(firstName) \(middleName ?? "") \(lastName)"
}
func greeting() -> String {
return "Hi, " + fullName()
}
}
struct User : PersonType {
let firstName: String
let middleName: String?
let lastName: String
func greeting() -> String{
return "Hey there, " + fullName()
}
func fullName() -> String {
return "\(lastName), \(firstName)"
}
}
let someUser = User(firstName: "Pasan", middleName: nil, lastName: "Premaratne")
let anotherUser: PersonType = User(firstName: "Gabriel", middleName: nil, lastName: "Nadel")
someUser.greeting() // outputs "Hey there, Premaratne, Pasan"
anotherUser.greeting() // outputs "Hi, Nadel, Gabriel"
Why doesn't anotherUser output "Hi, Gabriel Nadel" ?
2 Answers
David Keck
5,723 PointsWait. I think i've got it.
anotherUser's type is the PersonType protocol, and since protocols are first class citizens in Swift, they can be used as types. So, since the PersonType protocol dictates that anotherUser must conform by having a fullName function, the fullName function that is called by anotherUser is the one defined by the struct User since anotherUser is really a User struct being cast to a PersonType protocol. Since the PersonType protocol does not dictate that anotherUser must have a definition for greeting, anotherUser uses the function declared inside of the PersonType extension, having already forgone the User struct definition of greeting when it was cast from User to PersonType protocol.
Whew. Can someone check me on that?
Boris Likhobabin
3,581 PointsThere is a rule, that Gabe said we should remember so that is my take on it. Try not to apply logic here but just remember:
If inferred type of a class/struct is a protocol type and the original protocol(without extension) defines a particular method, then that method's implementation is taken from a class/struct If it is NOT DEFINED in the original protocol, the implementation of that method is taken from the protocol extension's default implementation. (despite being defined in class/struct)
So in this particular case function fullname() IS defined in original protocol PersonType, therefore by the rule above anotherUser uses the implemetation defined in a struct. i.e. "....... , Premaratne, Pasan" In contrast you see that greeting() method is not defined in the original protocol so by the rule anotherUser implements greetings() from protocol extension i.e. "Hi, ......."
David Keck
5,723 PointsDavid Keck
5,723 PointsWould anyone like to check my understanding on this one? Please? :)