我有一个带有类func的基类:
class BaseModel
{
class func getObjectWithId(_ id: String, completionHandler: @escaping (<???>) -> ())
{
// does query, calls completionHandler with matching object
}
}
我有两个子课程:
class Cat: BaseModel { //whatever }
class Dog: BaseModel { //whatever }
我希望能够在子类上调用该类方法,并使用子类型的对象调用完成处理程序:
Cat.getObjectWithId("1") { (theCat) in
// I want theCat to be of type Cat, not BaseModel
}
Dog.getObjectWithId("1") { (theDog) in
// I want theDog to be of type Dog, not BaseModel
}
我修饰了仿制药,但承认这不是我的力量......
我不想在每个基类中为此编写代码b / c除了类型之外它是相同的(即我不想要每个孩子必须实现的协议)。
我不想要一个将类型作为参数的类方法。我真的非常喜欢我的示例方法调用的简单性。
答案 0 :(得分:0)
您可以尝试以下代码:
class BaseModel
{
class func getObjectWithId<T: BaseModel>(_ id: String, completionHandler: @escaping (T) -> ())
{
// does query, calls completionHandler with matching object
}
}
但你必须明确地专门化这样的类型
Cat.getObjectWithId("1") { (theCat: Cat) in
// I want theCat to be of type Cat, not BaseModel
}
Dog.getObjectWithId("1") { (theDog: Dog) in
// I want theDog to be of type Dog, not BaseModel
}
但更安全的方法是在你想要的每个班级中复制函数getObjectWithId
。
答案 1 :(得分:0)
我最终在Anton的建议中采用了混合方法,并做了一些我原本不想做的事情:
我几乎完全像Anton一样创建了该方法的基本版本,除了它还需要数据类型(我最初想要避免的):
class BaseModel
{
class func getObjectWithId<T: BaseModel>(_ id: String, type: T.Type, completionHandler: @escaping (T?) -> ())
{
// does query, calls completionHandler with matching object
}
}
子类具有自己的专用方法,可以调用该基类方法:
class Dog: BaseModel
{
class func getDogWithId(_ dogId: String, completionHandler: @escaping (Dog?) -> ()
{
BaseModel.getObjectWithId(dogId, objectType: Dog.self) { (dog) in
completionHandler(dog)
}
}
}
Con:在每个子类中为此方法创建签名很烦人(它甚至不再继承,但由于其他原因我仍然需要基类)。
亲:很不错,因为我不必重复每个子课程中代码的内容,
亲:每次调用子类方法时,我都不必投出结果。