SLN SLN - 6 months ago 12
Swift Question

Where is the property that do not conform to the protocol goes?

Teacher
&
TeamMate
are two protocols. The class
Coach
conforms to those protocols.

protocol Teacher {
var firstName: String { get }
var lastName: String { get }
var title: String { get }
}

protocol TeamMate {
var firstName: String { get }
func role()
}

class Coach: Teacher, TeamMate {
var firstName: String
var lastName: String
var title: String

func role() {
print("coach the team")
}

init(firstName: String, lastName: String, title: String){
self.firstName = firstName
self.lastName = lastName
self.title = title
}
}

var member: TeamMate = Coach(firstName: "Izumi", lastName: "Yakuza", title: "LA Coach")


I've created a variable named
member
of type
coach
meanwhile it conforms to the
TeamMate
type (Please correct me if the description is not accurate)

I need to initialise all the properties defined in the
Coach
class when I create the
member
object. I.e.
(firstName: "Izumi", lastName: "Yakuza", title: "LA Coach")
. However, in the end, there is only one property
firstName
and one method
role()
inside the
member
instance.

enter image description here

Question: How the properties (
lastName: "Yakuza", title: "LA Coach"
) were processed? Is that they were created firstly and then cut away or just hidden?

Thanks a lot for your kind help and time.

Answer

I've created a variable named member of type coach meanwhile it conforms to the TeamMate type

var member: TeamMate = Coach(firstName: "Izumi", lastName: "Yakuza", title: "LA Coach")

I suspect this line of code isn't doing what you think it's doing. Your member variable isn't of type Coach, you've upcast to the abstract type TeamMate (a protocol which Coach conforms to). Therefore when using your variable, you can only access members that TeamMate defines (firstName and role()) – which is the exact behaviour you're seeing.

Unless you need to you shouldn't upcast your variables, as upcasting loses type information. In most cases, you should just let Swift infer the correct type for you. In your case member should almost certainly be of type Coach (you can always freely pass it to anything expecting a TeamMate, as Coach conforms to this protocol).

Therefore, you just want to drop the explicit type annotation:

var member = Coach(firstName: "Izumi", lastName: "Yakuza", title: "LA Coach")

You should also make it a let constant if you don't plan on mutating it.