W Swift mogę jawnie ustawić typ zmiennej, deklarując ją w następujący sposób:
var object: TYPE_NAME
Jeśli chcemy pójść o krok dalej i zadeklarować zmienną, która jest zgodna z wieloma protokołami, możemy użyć protocol
deklaratywnego:
var object: protocol<ProtocolOne,ProtocolTwo>//etc
A co jeśli chciałbym zadeklarować obiekt, który jest zgodny z jednym lub kilkoma protokołami, a także ma określony typ klasy bazowej? Odpowiednik Objective-C wyglądałby następująco:
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
W Swift spodziewałbym się, że będzie to wyglądać tak:
var object: TYPE_NAME,ProtocolOne//etc
Daje nam to elastyczność, ponieważ jesteśmy w stanie poradzić sobie z implementacją typu podstawowego, a także dodanym interfejsem zdefiniowanym w protokole.
Czy jest inny bardziej oczywisty sposób, którego mógłbym przegapić?
Przykład
Jako przykład załóżmy, że mam UITableViewCell
fabrykę, która jest odpowiedzialna za zwrot komórek zgodnych z protokołem. Możemy łatwo ustawić ogólną funkcję, która zwraca komórki zgodne z protokołem:
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
później chcę usunąć z kolejki te komórki, wykorzystując zarówno typ, jak i protokół
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
Zwraca to błąd, ponieważ komórka widoku tabeli nie jest zgodna z protokołem ...
Chciałbym móc określić, że komórka jest a UITableViewCell
i jest zgodna z MyProtocol
deklaracją w zmiennej?
Usprawiedliwienie
Jeśli znasz wzorzec fabryki, miałoby to sens w kontekście możliwości zwracania obiektów określonej klasy, które implementują określony interfejs.
Tak jak w moim przykładzie, czasami lubimy definiować interfejsy, które mają sens, gdy są stosowane do konkretnego obiektu. Mój przykład komórki widoku tabeli jest jednym z takich uzasadnień.
Chociaż dostarczony typ nie jest dokładnie zgodny ze wspomnianym interfejsem, obiekt zwracany przez fabrykę ma, dlatego chciałbym mieć elastyczność w interakcji zarówno z typem klasy bazowej, jak iz deklarowanym interfejsem protokołu