В Swift я могу явно задать тип переменной, объявив ее следующим образом:
var object: TYPE_NAME
Если мы хотим сделать еще один шаг и объявить переменную, которая соответствует нескольким протоколам, мы можем использовать декларацию protocol
:
var object: protocol<ProtocolOne,ProtocolTwo>//etc
Что делать, если я хотел бы объявить объект, который соответствует одному или нескольким протоколам, а также относится к конкретному типу базового класса? Эквивалент Objective-C будет выглядеть следующим образом:
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
В Swift я ожидаю, что он будет выглядеть так:
var object: TYPE_NAME,ProtocolOne//etc
Это дает нам гибкость в том, чтобы иметь дело с реализацией базового типа, а также с добавленным интерфейсом, определенным в протоколе.
Есть ли еще более очевидный способ, которым я мог бы не хватать?
Пример
В качестве примера, скажем, у меня есть UITableViewCell
factory, который отвечает за возврат ячеек, соответствующих протоколу. Мы можем легко настроить общую функцию, которая возвращает ячейки, соответствующие протоколу:
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
позже я хочу удалить эти ячейки, используя как тип, так и протокол
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
Это возвращает ошибку, поскольку ячейка представления таблицы не соответствует протоколу...
Я хотел бы указать, что ячейка является UITableViewCell
и соответствует MyProtocol
в объявлении переменной?
Оправдание
Если вы знакомы с шаблоном Factory, это будет иметь смысл в контексте возможности возврата объектов определенного класса, реализующего определенный интерфейс.
Как и в моем примере, иногда нам нравится определять интерфейсы, которые имеют смысл при применении к определенному объекту. Мой пример ячейки представления таблицы является одним из таких оправданий.
Пока поставляемый тип точно не соответствует указанному интерфейсу, возвращается объект factory, поэтому мне нужна гибкость при взаимодействии как с типом базового класса, так и с объявленным интерфейсом протокола