Now, we want to declare a PartyProtocol
protocol and make the generic Party<AnimalElement>
class conform to this new protocol. The main challenge is to specify the type for both the method arguments and returned values. In the generic class, we will use the generic type parameter, but protocols don't allow us to use them.
Associated types allow us to solve the problem. We can declare one or more associated types as part of the protocol definition. In this case, we just need one associated type to provide us with a placeholder name---also known as alias---to a type that we will use as part of the protocol and that will be specified during the protocol implementation, that is, when we declare a class that conforms to the protocol. It is just necessary to use the associatedtype
keyword followed by the desired name for the associated type, and then, we can use the name in our requirements' declarations.
The following lines show the declaration of the PartyProtocol
protocol. We must declare the protocol before the open class Party<AnimalElement: AnimalProtocol> where AnimalElement: Equatable {
line that starts the declaration of the Party<AnimalElement>
class that we want to edit to make it conform to this new protocol. The code file for the sample is included in the swift_3_oop_chapter_06_08
folder:
public protocol PartyProtocol { associatedtype MemberType init(leader: MemberType) func createAndAddMember(name: String) -> MemberType func add(member: MemberType) func remove(member: MemberType) throws -> MemberType? func dance() func sing() func voteLeader() throws }
The first line within the protocol body declares an associated type named MemberType
. Then, the initializer and method requirements use MemberType
to specify the type that the generic class that conforms to this protocol will replace with the generic type parameter name.
The following code shows the first lines of the new declaration of the Party<AnimalElement>
class that conforms to the recently created PartyProtocol
. After the type constraint included within angle brackets (< >
), the class declaration adds a colon (:
) followed by the protocol to which the generic class conforms: PartyProtocol
. Then, the declaration adds the where
keyword followed by the additional type constraint (AnimalElement: Equatable
). As we specified an initializer requirement in the PartyProtocol
protocol, we have to add public required
as a prefix before the init
declaration. The rest of the code for the class remains without changes. The following code shows the first lines of the declaration with the two lines that were edited, highlighted:
open class Party<AnimalElement: AnimalProtocol>: PartyProtocol where AnimalElement: Equatable { private var members = [AnimalElement]() open var leader: AnimalElement public required init(leader: AnimalElement) { self.leader = leader members.append(leader) } /* The rest of the code for the class remains without changes */ }
3.16.76.227