The following class:
class User {
var name = "Max"
var surname = "Mustermann"
}
and the following protocol:
protocol Sharable {
func share(name: String)
var isSharable: Bool { get set }
}
Extend the protocol sharable
in a way so that subclasses of User
get an implemented version of share(:)
and isSharable
.
The following extension attempts to do this:
extension Sharable where Self: User {
func share(name: String) { print(name) }
var isSharable: Bool { return !name.isEmpty }
}
The created subclass Admin
should get all functionality of Sharable
for free without storing and implementing variables and functions.
class Admin: User, Sharable {
}
But Xcode will print the error:
'Admin' does not conform to protocol 'Sharable'
Xcode proposes the following:
class Admin: User, Sharable {
var isSharable: Bool
}
Now Xcode prints the error:
class 'Admin' has no initializers
Is there a way to extend the protocol Sharable
so that Admin
has a variable isSharable
without defining or initializing it? Basically like it works with the function share(:)
, which has not to be implemented by the subclass because it is implemented by the extension.
class ArbitraryObject: User, Sharable {
// no implementation or initializing of isSharable or share(:)
}
let arbitraryObject = ArbitraryObject()
if arbitraryObject.isSharable {
arbitraryObject.share(name: arbitraryObject.name)
}
Currently your protocol defines isSharable
as { get set }
protocol Sharable {
func share(name: String)
var isSharable: Bool { get set }
}
This means that when you construct your extension it is not actually conforming to the protocol
extension Sharable where Self: User {
func share(name: String) { print(name) }
var isSharable: Bool { return !name.isEmpty }
}
This is due to the fact that you have defined isSharable
in your extension as a computed property. Computed properties are get
only.
You can make your extension conform to the Sharable
protocol by removing the set
requirement. So your protocol would become:
protocol Sharable {
func share(name: String)
var isSharable: Bool { get }
}