I am thinking on this for hours: Lets say you have a generic game. The game can have players and an methode that sets a score. This can be done by using a protocol:
protocol Game {
var players: [Player] {get set}
func setScore (for player: Player, value: Int)
func sendSomeMessage(message: String)
}
i can now create a struct confirming to the protocol "Game"
struct raiseGame: Game {
var players: [Player]()
func setScore (for player: Player, value: Int) {
player.score = value
}
func sendSomeMessage(message: String) {
players.forEach { player in
//send the message to each player
}
}
}
But then i have, lets say, another struct conforming to Game. But in this time the score should be decreased. All other things stay the same. Now i have to write all the code for the func sendSomeMessage again. (There could be many more functions which stays the same).
The question is now: Should i switch to a class, write a base class and inherit from it, or is there a way to provide somekind of default implementations for functions in protocols, so i don't need to write them every time again, when confirming to a protocol?
CodePudding user response:
is there a way to provide somekind of default implementations for functions in protocols, so i don't need to write them every time again, when confirming to a protocol?
There is indeed a way to provide default method implementations for protocol-conforming types:
protocol MyProtocol {
func myMethodRequirement()
}
extension MyProtocol {
func myMethodRequirement() {
// Default implementation.
}
}
struct Foo: MyProtocol {
func myMethodRequirement() {
// Foo-specific implementation.
}
}
struct Bar: MyProtocol {
/* Inherits default implementation instead. */
}
In your case, giving sendSomeMessage(message:) a default implementation would look like:
extension Game {
func sendSomeMessage(message: String) {
// Default implementation here.
}
}
Any type conforming to Game could either implement sendSomeMessage(message:) itself (similar to override-ing a method in a class), or use the default implementation without doing any additional work.
For more information, you can see the "Providing Default Implementations" section on protocols of the The Swift Programming Language guide.
To answer the title of your question, then, given that it is possible to do this for structs:
- A
classmay be useful over astructif you have an inheritance hierarchy multiple levels deep, which may be more complicated to express using protocol conformances - A
classmay be useful over astructwhen you need reference semantics — see:
In your specific case, it doesn't immediately appear that either of these apply, but with more information, it might become obvious whether switching would be beneficial or not.
