Ответ
Протокол определяет интерфейс (требуемые свойства и методы), который должны реализовать соответствующие ему типы (классы, структуры, перечисления).
Пример:
// 1. Объявление протокола
protocol Vehicle {
var numberOfWheels: Int { get }
func startEngine()
}
// 2. Реализация протокола классом
class Car: Vehicle {
let numberOfWheels = 4
func startEngine() {
print("Car engine started")
}
}
// 3. Реализация протокола структурой
struct Bike: Vehicle {
let numberOfWheels = 2
func startEngine() {
print("Bike pedaling started")
}
}
// 4. Использование полиморфизма
let vehicles: [Vehicle] = [Car(), Bike()]
for vehicle in vehicles {
print("Wheels: (vehicle.numberOfWheels)")
vehicle.startEngine()
}
Почему это полезно:
- Полиморфизм: Массив
[Vehicle]может хранить объекты разных типов, но с общим интерфейсом. - Проектирование: Протоколы позволяют определять контракты и абстрагироваться от конкретной реализации.
- Тестирование: Облегчают создание мок-объектов для модульного тестирования.
Ответ 18+ 🔞
Да ты посмотри, какая хуйня интересная! Ну, в смысле, протоколы в свифте. Представь себе, что протокол — это как бумажка от жены с требованиями на день. Там написано: «Должен иметь свойство numberOfWheels (количество колёс) и уметь выполнять метод startEngine() (заводить движок)». И неважно, кто ты — мужик на тачке или хипстер на велике. Если к тебе пришла эта бумажка, ты, блядь, обязан эти пункты выполнить, иначе пиздец.
Вот смотри, как это выглядит в коде, тут всё чётко:
// 1. Вот та самая бумажка-приказ, протокол
protocol Vehicle {
var numberOfWheels: Int { get }
func startEngine()
}
// 2. Класс "Тачка" получает бумажку и чешет затылок: "Ну ладно..."
class Car: Vehicle {
let numberOfWheels = 4 // «Имею четыре колеса, мать их, вот они!»
func startEngine() {
print("Car engine started") // «Движок завёлся, врум-врум!»
}
}
// 3. Структура "Велик" тоже не лыком шита, принимает вызов
struct Bike: Vehicle {
let numberOfWheels = 2 // «Два колеса, ёпта, и гордиться нечем»
func startEngine() {
print("Bike pedaling started") // «Движок — это мои ноги, поехали!»
}
}
А теперь самое охуенное! Берём их всех — и тачку, и велик — и суём в один массив [Vehicle]. И похуй, что они разные! Главное — у каждого есть numberOfWheels и метод startEngine(). И мы можем пройтись по массиву и каждого заставить эти штуки показать.
// 4. Собираем зоопарк транспорта в одну кучу
let vehicles: [Vehicle] = [Car(), Bike()]
for vehicle in vehicles {
print("Wheels: (vehicle.numberWheels)") // Спрашиваем колёса
vehicle.startEngine() // Приказываем завестись
}
И нахуя это всё, спросишь? А вот нахуя:
- Полиморфизм, ёпта! Это когда ты можешь в одну переменную или массив запихнуть что угодно —
Car,Bike,Tank— лишь бы они подписались под один протокол. И потом со спокойной жопой вызывать у всех общие методы. Удобно, блядь, как! - Проектирование от хуя к пальцу. Сначала думаешь, что должен уметь объект (пишешь протокол), а потом уже лепишь под него реализацию. Не наоборот, чтобы не получилась каша из говна и палок.
- Тестирование без боли. Хочешь протестировать какой-нибудь модуль, который ждёт объект
Vehicle? Да похуй! Сделай на коленке «пустышку» —MockVehicle, которая реализует протокол, но внутри просто пишет в лог. И тестируй на здоровье, не разоряя гараж.
Короче, протоколы — это сила. Они заставляют код держать лицо и не выёбываться.