In Swift kann ich den Typ einer Variablen explizit festlegen, indem ich ihn wie folgt deklariere:
var object: TYPE_NAME
Wenn wir noch einen Schritt weiter gehen und eine Variable deklarieren möchten, die mehreren Protokollen entspricht, können wir das protocol
Deklarativ verwenden:
var object: protocol<ProtocolOne,ProtocolTwo>//etc
Was ist, wenn ich ein Objekt deklarieren möchte, das einem oder mehreren Protokollen entspricht und auch von einem bestimmten Basisklassentyp ist? Das Objective-C-Äquivalent würde folgendermaßen aussehen:
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
In Swift würde ich erwarten, dass es so aussieht:
var object: TYPE_NAME,ProtocolOne//etc
Dies gibt uns die Flexibilität, die Implementierung des Basistyps sowie die im Protokoll definierte zusätzliche Schnittstelle durchführen zu können.
Gibt es einen anderen offensichtlicheren Weg, den ich vermissen könnte?
Beispiel
Angenommen, ich habe eine UITableViewCell
Fabrik, die für die Rückgabe von Zellen gemäß einem Protokoll verantwortlich ist. Wir können leicht eine generische Funktion einrichten, die Zellen zurückgibt, die einem Protokoll entsprechen:
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
Später möchte ich diese Zellen aus der Warteschlange entfernen und dabei sowohl den Typ als auch das Protokoll nutzen
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
Dies gibt einen Fehler zurück, da eine Tabellenansichtszelle nicht dem Protokoll entspricht ...
Ich möchte angeben können, dass die Zelle a ist UITableViewCell
und der MyProtocol
in der Variablendeklaration entspricht.
Rechtfertigung
Wenn Sie mit dem Factory-Muster vertraut sind, ist dies sinnvoll, wenn Sie Objekte einer bestimmten Klasse zurückgeben können, die eine bestimmte Schnittstelle implementieren.
Genau wie in meinem Beispiel möchten wir manchmal Schnittstellen definieren, die sinnvoll sind, wenn sie auf ein bestimmtes Objekt angewendet werden. Mein Beispiel für die Zelle der Tabellenansicht ist eine solche Rechtfertigung.
Der angegebene Typ entspricht zwar nicht genau der genannten Schnittstelle, das von der Factory zurückgegebene Objekt jedoch. Daher möchte ich die Flexibilität bei der Interaktion sowohl mit dem Basisklassentyp als auch mit der deklarierten Protokollschnittstelle
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
. Dieses Objekt scheint ziemlich nutzlos zu sein, da es NSSomething
bereits weiß, wozu es passt. Wenn es entspricht nicht einem der Protokolle in <>
Sie bekommen unrecognised selector ...
stürzt ab. Dies bietet überhaupt keine Typensicherheit.