The Error is correct. You have to make your class final, since no subclasses could conform your protocol Ownee
.
Consider this subclass:
class FirstGradeStudent: Student {
// inherited from parent
// var owner: Owner<Student> {
// return professor
// }
}
As you can see, it would have to implement var owner: Owner<Student>
because of his parent, but it should be implementing var owner: Owner<FirstGradeStudent>
instead, because the protocol contains var owner: Owner<Self> { get }
and in this case Self
would be FirstGradeStudent
.
Workaround
1: Define a superclass to Ownee
, it should be used by Owner
:
class Owner<T: OwneeSuper> {
// ...
}
protocol OwneeSuper {}
protocol Ownee: OwneeSuper {
associatedtype T: OwneeSuper
var owner: Owner<T> { get }
}
OwneeSuper
is just a workaround to overcome this problem, otherwise we would just be using:
protocol Ownee {
associatedtype T: Ownee
var owner: Owner<T> { get }
}
2. In classes that conform to Ownee
, you must turn the abstract type of the associatedtype
into a concrete class by defining a typealias
:
class Student: Ownee {
typealias T = Student // <<-- define the property to be Owner<Student>
let professor: Professor
var owner: Owner<T> {
return professor
}
init(professor: Professor) {
self.professor = professor
}
}
3. Subclasses can now make use of the property, which will be of your defined type:
class FirstGradeStudent: Student {
func checkOwnerType() {
if self.owner is Owner<Student> { //warning: 'is' test is always true
print("yeah!")
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…