Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 泛型类与继承_Swift_Generics - Fatal编程技术网

Swift 泛型类与继承

Swift 泛型类与继承,swift,generics,Swift,Generics,我有一个模型对象: class Animal { // ... } class Animal { // ... } 和子类: class Dog: Animal { // ... } class Cat: Animal { // ... } class Dog: Animal { // ... } class Cat: Animal { // ... } 我还创建了泛型类 class AnimalController<T: Animal> { var anim

我有一个模型对象:

class Animal {
// ...
}
class Animal {
// ...
}
和子类:

class Dog: Animal {
// ...
}

class Cat: Animal {
// ...
}
class Dog: Animal {
// ...
}

class Cat: Animal {
// ...
}
我还创建了泛型类

class AnimalController<T: Animal> {
      var animal: T? 
      func feed(animal: T) {
          let food = Food(T.self)
          animal.feed(food)
      }
}
class AnimalController<T> {
    var type: T

    init(type: T) {
        self.type = type
    }

    func feed() {
        if type is Animal.Type {
            let food = Food(type as! Animal.Type)
            animal.feed(food)
        }
    }
}
和子类:

class Dog: Animal {
// ...
}

class Cat: Animal {
// ...
}
class Dog: Animal {
// ...
}

class Cat: Animal {
// ...
}
我还创建了泛型类

class AnimalController<T: Animal> {
      var animal: T? 
      func feed(animal: T) {
          let food = Food(T.self)
          animal.feed(food)
      }
}
class AnimalController<T> {
    var type: T

    init(type: T) {
        self.type = type
    }

    func feed() {
        if type is Animal.Type {
            let food = Food(type as! Animal.Type)
            animal.feed(food)
        }
    }
}
类动物控制器{
变量类型:T
初始化(类型:T){
self.type=type
}
func提要(){
如果类型是动物。类型{
让食物=食物(类型为!Animal.type)
动物饲料(食品)
}
}
}
现在它可以工作了:

class MainViewController: UIViewController {
      var controller: AnimalController<Animal>?

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // I want control a dog
        self.controller = AnimalController<Dog>()  // Works!
        self.controller = AnimalController<Cat>()  // Works!
    }
}
class MainViewController:UIViewController{
var控制器:动物控制器?
//马克:生命周期
重写func viewDidLoad(){
super.viewDidLoad()
//我想要一只狗
self.controller=AnimalController()//有效!
self.controller=AnimalController()//有效!
}
}

Swift是一种强类型语言。您已经声明了属性
controller
,不能更改其类型,但这完全没问题,因为Swift支持泛化范例,允许您使用公共超类保存属性中的对象。

这看起来像是应该使用继承而不是泛型的情况

class AnimalController {
    // basic animal control tasks
}


class CatController: AnimalController {
    // specialized controller just for cats
}
class DogController: AnimalController {
    // ...
}
那你就可以写了

class MainViewController: UIViewController {
    var animalController: AnimalController

    override func viewDidLoad() {
        super.viewDidLoad()

        // I want control a dog
        self.controller = DogController()

        // I want control a cat
        self.controller = CatController()
    }
}

在这种情况下,使用泛型可能会导致问题,因为Swift编译器会解决泛型类型并将其替换为具体类型(这是不可能的,除非您将整个视图控制器设置为泛型,但这将与interface builder配合使用)

在您的示例中,无需将
AnimalController
设为泛型类。它可以有一些简单的方法来处理
动物
,它们可以通过继承来处理

class Animals {
    // ...
}

class Dog: Animals {
    // ...
}

class Cat: Animals {
    // ...
}

class AnimalController {
    // methods to control any kind of animals
    var animal: Animals? // Will take both cats and dogs
    func feed(animal: Animals) {
        // Will take both cats and dogs
    }
}

class MainViewController: UIViewController {
    var controller: AnimalController?

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // I want control a dog or a cat
        self.controller = AnimalController()

        let cat = Cat()
        controller?.animal = cat
        controller?.feed(animal: cat)

        let dog = Dog()
        controller?.animal = dog
        controller?.feed(animal: dog)
    }
}
(更新)

即使在编辑之后,我也不认为需要泛型:

class Animal {
    // ...
    func feed(_ food: Food){
        // feed the animal or maybe throw an error
        // if subclasses must implement
    }
}

class Dog: Animal {
    // ...
    override func feed(_ food: Food) {
        // feed a cat
    }
}

class Cat: Animal {
    // ...
    override func feed(_ food: Food) {
        // feed a dog
    }
}

class Food {
    init(_ animalType: Animal.Type) {
        // Make food
    }
}

class AnimalController {
    // methods to control any kind of animals
    var animal: Animal? // Will take both cats and dogs
    func feed(animal: Animal) {
        // Will take both cats and dogs
        let food = Food(type(of: animal))
        animal.feed(food)
    }
}

class MainViewController: UIViewController {
    var controller: AnimalController?

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // I want control a dog or a cat
        self.controller = AnimalController()

        let cat = Cat()
        controller?.animal = cat
        controller?.feed(animal: cat)

        let dog = Dog()
        controller?.animal = dog
        controller?.feed(animal: dog)
    }
}

你的类不太通用:-)我建议你阅读苹果文档中关于泛型的章节拼写错误。很抱歉问题是泛型是不变量的,比较和你编辑的代码没有可能的方式——考虑你是否能够将<代码> AnimalController < /代码>分配给<代码> AnimalController < /代码>。然后你可以说
controller?.feed(动物:Cat())
。你刚刚给一只猫喂了狗粮。谢谢哈米什。我阅读了链接并给出了解决方案。我编辑我的问题并添加答案。在控制器中猫/狗之间没有区别。这将是相同的使用您的代码,我们有重复的代码。不同之处在于模型。显然,猫和狗有不同的属性。谢谢如果是这样的话,你只需要动物控制器,而不是两个子类。其余的都一样。首先,谢谢你的回答。这是有道理的,但在我的原始代码中,猫和狗之间的“feed”方法必须不同。我在解释中添加了该方法,以便更清楚地揭示问题。最初的方法使用带有该模式的领域对象类,但我不想让问题变得复杂,添加许多代码行。feed cat和dogs之间的区别只是将参数cat.self或Dog.self发送给算法中的其他对象。如果重写该方法,将复制多行代码。