Dans Swift, je peux définir explicitement le type d'une variable en la déclarant comme suit:
var object: TYPE_NAME
Si nous voulons aller plus loin et déclarer une variable conforme à plusieurs protocoles, nous pouvons utiliser le protocol
déclaratif:
var object: protocol<ProtocolOne,ProtocolTwo>//etc
Que faire si je souhaite déclarer un objet conforme à un ou plusieurs protocoles et qui est également d'un type de classe de base spécifique? L'équivalent Objective-C ressemblerait à ceci:
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
Dans Swift, je m'attendrais à ce que cela ressemble à ceci:
var object: TYPE_NAME,ProtocolOne//etc
Cela nous donne la flexibilité de pouvoir gérer l'implémentation du type de base ainsi que l'interface ajoutée définie dans le protocole.
Y a-t-il un autre moyen plus évident que je pourrais manquer?
Exemple
À titre d'exemple, disons que j'ai une UITableViewCell
usine qui est chargée de renvoyer des cellules conformes à un protocole. Nous pouvons facilement configurer une fonction générique qui retourne des cellules conformes à un protocole:
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
plus tard, je veux retirer ces cellules de la file d'attente tout en exploitant à la fois le type et le protocole
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
Cela renvoie une erreur car une cellule de vue tableau n'est pas conforme au protocole ...
Je voudrais pouvoir spécifier que la cellule est a UITableViewCell
et est conforme à la MyProtocol
dans la déclaration de variable?
Justification
Si vous êtes familier avec le modèle d'usine, cela aurait du sens dans le contexte de pouvoir renvoyer des objets d'une classe particulière qui implémentent une certaine interface.
Tout comme dans mon exemple, nous aimons parfois définir des interfaces qui ont du sens lorsqu'elles sont appliquées à un objet particulier. Mon exemple de cellule de vue tableau est une de ces justifications.
Bien que le type fourni ne soit pas exactement conforme à l'interface mentionnée, l'objet renvoyé par l'usine le fait et j'aimerais donc avoir la flexibilité d'interagir avec le type de classe de base et l'interface de protocole déclarée
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
. Cet objet semble tout à fait inutile car il NSSomething
sait déjà à quoi il se conforme. S'il n'est pas conforme à l'un des protocoles de, <>
vous obtiendrez des unrecognised selector ...
plantages. Cela n'offre aucune sécurité de type.