问题
(if someone can suggest a better title, please do)
The following code does not compile with an error Type 'ObserverClass' does not conform to protocol 'Observer'
, and compiler suggests a fix by declaring var object: ObservedObject
.
class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}
protocol Observer {
var object: ObservedObject { get }
}
class ObserverClass: Observer { // Type 'ObserverClass' does not conform to protocol 'Observer'
// suggested:
// var object: ObservedObject
var object: ObservedObjectSubclass = ObservedObjectSubclass()
}
The way i see it - ObservedObjectSubclass
is ObservedObject
, and so object
property is guaranteed to be of type ObservedObject
as required by the protocol.
(The same is true, if using protocol conformance instead of subclassing - below)
protocol ObservedObjectProtocol {}
protocol Observer {
var object: ObservedObjectProtocol { get }
}
class ObservedObject: ObservedObjectProtocol {}
class ObserverClass: Observer { // same error
var object: ObservedObject = ObservedObject()
}
Why is compiler unhappy? Is it current limitation, or the compiler is actually right and there is some logical constraint?
回答1:
When you define a variable in a protocol and assign a type to it, that is going to be a concrete type, so you cannot change it to a subclass of that type when conforming to the protocol. The type of the variable declared in the conforming class must be the same type as declared in the protocol, it cannot be a covariant (inheritance related) type.
You can fix the second error by creating an associatedType
for your Observer
protocol, which inherits from ObserverObject
then you can define object
to be of the same type as your associated type. Then you can make your ObserverClass
have a property object
of type ObservedObjectSubclass
.
class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}
protocol Observer {
associatedtype ObjectSubclass: ObservedObject
var object:ObjectSubclass { get }
}
class ObserverClass: Observer {
var object = ObservedObjectSubclass()
}
来源:https://stackoverflow.com/questions/48433737/swift-protocol-conformance-requirements-for-subtypes