I want to encapsulate a generic object in another class without setting the generic type argument. I created a base Animal<T>
class and defined other subclasses from it. Example:
public class Animal<T: YummyObject> {
// Code
}
public class Dog: Animal<Bark> {
// Code
}
public class Cat: Animal<Meow> {
// Code
}
and defined an Animal
property, without the type argument, in the UITableView
extension bellow:
extension UITableView {
private static var animal: Animal!
func addAnimal(animal: Animal) {
UITableView.animal = animal
}
}
but I get the following compile error when doing so:
Reference to generic type
Animal
requires arguments in<...>
.
This seems to work fine in Java. How can I accomplish the same thing in Swift as well?
Swift doesn’t yet support wildcard-style generics like Java does (i.e., Animal<?>
). As such, a common pattern is to define a type-erased superclass, protocol (or wrapper) to enable such usage instead. For instance:
public class AnyAnimal {
/* non-generic methods */
}
and then use it as your superclass:
public class Animal<T: YummyObject>: AnyAnimal {
...
}
Finally, use AnyAnimal
in your non-generic code instead:
private static var animal: AnyAnimal!
Examples in the Swift Standard Library. For a practical example, see the KeyPath
, PartialKeyPath
, and AnyKeyPath
classes hierarchy. They follow the same pattern I outlined above. The Collections framework provides even further type-erasing examples, but using wrappers instead.
来源:https://stackoverflow.com/questions/46498611/how-to-use-a-generic-class-without-the-type-argument-in-swift