In Swift posso impostare esplicitamente il tipo di una variabile dichiarandolo come segue:
var object: TYPE_NAME
Se vogliamo fare un ulteriore passo avanti e dichiarare una variabile conforme a più protocolli, possiamo usare il protocol
dichiarativo:
var object: protocol<ProtocolOne,ProtocolTwo>//etc
E se volessi dichiarare un oggetto conforme a uno o più protocolli ed è anche di un tipo di classe base specifico? L'equivalente Objective-C sarebbe simile a questo:
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
In Swift mi aspetto che assomigli a questo:
var object: TYPE_NAME,ProtocolOne//etc
Questo ci offre la flessibilità di poter gestire l'implementazione del tipo di base e l'interfaccia aggiunta definita nel protocollo.
C'è un altro modo più ovvio in cui potrei mancare?
Esempio
Ad esempio, diciamo che ho una UITableViewCell
fabbrica che è responsabile della restituzione delle cellule conformi a un protocollo. Possiamo facilmente impostare una funzione generica che restituisce celle conformi a un protocollo:
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
in seguito desidero rimuovere dalla coda queste celle sfruttando sia il tipo che il protocollo
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
Ciò restituisce un errore perché una cella della vista tabella non è conforme al protocollo ...
Vorrei essere in grado di specificare che la cella è una UITableViewCell
e è conforme alla MyProtocol
nella dichiarazione della variabile?
Giustificazione
Se si ha familiarità con Factory Pattern, ciò avrebbe senso nel contesto della possibilità di restituire oggetti di una particolare classe che implementano una determinata interfaccia.
Proprio come nel mio esempio, a volte ci piace definire interfacce che abbiano senso quando applicate a un particolare oggetto. Il mio esempio della cella della vista tabella è una di queste giustificazioni.
Sebbene il tipo fornito non sia esattamente conforme all'interfaccia menzionata, l'oggetto restituito dalla fabbrica lo fa e quindi vorrei la flessibilità nell'interagire sia con il tipo di classe base che con l'interfaccia del protocollo dichiarato
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
. Questo oggetto sembra abbastanza inutile in quanto NSSomething
sa già a cosa è conforme. Se non è conforme a uno dei protocolli, <>
si verificheranno dei unrecognised selector ...
crash. Ciò non fornisce alcuna sicurezza di tipo.