泛型类和继承

时间:2017-06-04 12:35:02

标签: swift generics

我有模型对象:

class 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 MainViewController: UIViewController {
      var controller: AnimalController<Animal>?

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // I want control a dog
        self.controller = AnimalController<Dog>()  // Error

        // I want control a cat
        self.controller = AnimalController<Cat>()  // Error
    }
}

我怎样才能创建与狗和猫兼容的通用类?谢谢!

更新哈米什给我链接其他两个帖子的解决方案。

我有模型对象:

class Animal {
// ...
}

和子类:

class Dog: Animal {
// ...
}

class Cat: Animal {
// ...
}

我也创建了泛型类

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 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!
    }
}

3 个答案:

答案 0 :(得分:0)

Swift是一种强大的语言。您已经声明了属性// get the `UploadedFile` object $file = $request->file('file_name'); $file = $request->file_name; // get the original file name $filename = $request->file('file_name')->getClientOriginalName(); $filename = $request->file_name->getClientOriginalName(); ,并且您无法更改其类型,但这完全没问题,因为Swift支持泛化范例,它允许您使用公共超类将属性保存在属性中。 / p>

答案 1 :(得分:0)

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

$('.checkbox-primary').change(function () {
    $(this).is(":checked") {
          // checkbox is checked
    } else {
          // It is unchecked
    }
}

然后你可以写

class AnimalController {
    // basic animal control tasks
}


class CatController: AnimalController {
    // specialized controller just for cats
}
class DogController: AnimalController {
    // ...
}

在这种情况下使用泛型可能会导致问题,因为Swift编译器会解析泛型类型并用具体类型替换它们(除非你使整个视图控制器通用但这对接口构建器很好),否则这是不可能的。 p>

答案 2 :(得分:0)

在您的示例中,没有必要使AnimalController成为通用类。它可以很简单地使用适用于Animals的方法,它们可以通过继承在DogCat上工作。

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)
    }
}