Swift:协变覆盖?

标签 swift covariance

有什么方法可以在 Swift 中支持协变返回类型吗?

例如,我想支持以下场景:

class Animal {}
class Dog : Animal{}
class Cat : Animal {}

class AnimalResidency{
    func getAllAnimals() -> Array<Animal> {
        return []
    }
}
class Cattery : AnimalResidency{
    override func getAllAnimals() -> Array<Cat> {
        return [Cat(), Cat()]
    }
}
class DogKennel : AnimalResidency {
    override func getAllAnimals() -> Array<Dog> {
        return [Dog(), Dog(), Dog(), Dog()]
    }
}

覆盖的函数会产生编译器错误,因为覆盖签名与基本定义不完全匹配,即使很明显看到覆盖返回的内容仍符合基本定义的约定。

我有什么方法可以实现上述目标吗?我什至很感激 Swift 3 的答案。

最佳答案

我不确定是否有必要完全您所要求的 - 即覆盖 getAllAnimals 而不是重载它。使用泛型是一种可能的解决方案 - 看看这是否适合您:

class Animal { var description: String { return "Animal" } }
class Dog : Animal { override var description: String { return "Dog" } }        
class Cat : Animal { override var description: String { return "Cat" } }

class AnimalResidency<T: Animal>{
    func getAllAnimals<T>() -> Array<T> {
        return []
    }
}

class Cattery : AnimalResidency<Cat> {
    func getAllAnimals() -> Array<Cat> {
        return [Cat()]
    }
}

class DogKennel : AnimalResidency<Dog> {
    func getAllAnimals() -> Array<Dog> {
        return [Dog(), Dog()]
    }
}

let c = Cattery()
c.getAllAnimals().first?.description // "Cat"
let d = DogKennel()
d.getAllAnimals().first?.description // "Dog"

然而,我自己的想法不会使用两个平行的类层次结构,而是尝试更像这样的东西......

class Animal {
    var description: String { return "Animal" }
    required init() {}
}
class Dog : Animal {
    override var description: String { return "Dog" }
}
class Cat : Animal {
    override var description: String { return "Cat" }
}

extension Animal {
    class func home() -> [Animal] {
        return [self.init()]
    }
}

let c = Cat.home().first?.description // "Cat"
let d = Dog.home().first?.description // "Dog"

关于Swift:协变覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39332630/

相关文章:

ios - 将一个数组类型的解析对象设置为 tableView

arrays - 快速将 PFObject 数组转换为自定义 PFSubclass

arrays - 解析多个 JSON 对象

c# - 为什么 .NET 4.0 协方差在此示例中不起作用?

c# - 为什么 C# (4.0) 不允许通用类类型中的协变和逆变?

ios - 如何让数组一一显示在标签上

scala - 如何初始化协变变量?

F# 和接口(interface)协方差 : what to do?(特别是 seq<> aka IEnumerable<>)

c++ - 返回专用模板类的协变类型

swift - 如何使用 Swift 将游戏的高分保存在排行榜上?