В чем разница между протоколом в Swift и интерфейсом в языках типа Java или C#?

Ответ

Протокол (Swift) и интерфейс (Java, C#, etc.) — оба определяют контракт (набор методов и свойств), который должен быть реализован другими типами. Ключевые различия лежат в возможностях.

Аспект Протокол (Swift) Интерфейс (Классический, e.g., Java <8)
Реализация по умолчанию Да, через расширения (extensions). Нет (до Java 8). В Java 8+ — default методы.
Типы, которые могут соответствовать Классы, структуры, перечисления. Только классы (и record в C#).
Наследование Протокол может наследовать несколько других протоколов. Интерфейс может расширять несколько других интерфейсов.
Опциональные требования Да, через модификатор @objc (только для совместимости с Objective-C). Нет, все методы обязательны (кроме default).
Хранение состояния (свойства) Может требовать get/set свойств. Реализуется как вычисляемые или хранимые свойства. Может требовать только get/set методы (фактически — свойства в C#).

Пример протокола Swift с реализацией по умолчанию:

protocol Renderable {
    func draw()
    var opacity: Double { get set }
}
// Реализация по умолчанию через extension
extension Renderable {
    func draw() {
        print("Rendering with opacity (opacity)")
    }
}
// Структура, использующая реализацию по умолчанию
struct Circle: Renderable {
    var opacity: Double // Должна реализовать только свойство
    // Метод draw() уже предоставлен расширением
}

Итог: Swift-протоколы более гибкие благодаря расширениям и поддержке value-типов (структур).

Ответ 18+ 🔞

Слушай, давай разберём эту дичь, а то у меня уже глаза на лоб лезут от этих формальностей. Вот сидишь ты, такой весь в себе, думаешь: "Ну протокол, ну интерфейс... да одно и то же, ёпта!" А вот и нет, дружок-пирожок, разница есть, и она охуенно важная, особенно когда втыкаешься в код по уши.

Представь себе, что протокол в Swift — это как твой раздолбай-сосед, который говорит: "О, слушай, ты должен уметь играть на гитаре!" Но тут же, хитро так подмигивая, добавляет: "А вот тебе, кстати, разучил три блатных аккорда, можешь начинать с них, если своих мозгов не хватает". Это и есть реализация по умолчанию через расширения (extensions). Интерфейс же в старом-добром Java — это как суровый армейский прапорщик: "Ты должен уметь играть на гитаре! Точка. Никаких 'но' и 'возможно'. Не умеешь? Иди учи, пока не выучишь, тварь!"

И вот ещё прикол: протоколу вообще похуй, кто к нему приходит — класс, структура или даже перечисление. Всех берёт, всем рад. Интерфейс же в Java — старый консервативный пидарас, он общается только с классами. "Структуры? Это что ещё за мартышлюшки? Иди нахуй со своими value-типами", — примерно так он думает.

Смотри, как это выглядит в коде. Вот Swift со своими прибамбасами:

protocol Renderable {
    func draw()
    var opacity: Double { get set }
}
// А вот волшебная палочка — расширение
extension Renderable {
    func draw() {
        print("Rendering with opacity (opacity)")
    }
}
// И теперь наша структура-кружочек может быть немножко ленивой
struct Circle: Renderable {
    var opacity: Double // Реализовала только свойство
    // А метод draw() ей уже подарили, как сироте на праздник!
}

Видишь? Circle просто объявила свойство opacity, а метод draw() ей прилетел из расширения, как манна небесная. Красота, да и только! В старом Java пришлось бы писать этот метод вручную в каждом классе, и терпения ебать ноль к концу дня.

Итог, блядь, подведём: Swift-протоколы — это как продвинутый, гибкий инструмент с кучей примочек. Они позволяют накормить реализацией по умолчанию, дружат со всеми типами подряд и вообще ведут себя как современные, адекватные сущности. Классические интерфейсы — это более строгие, блядь, контракты без скидок на слабость. Выбирай, что тебе ближе по душе: получить готовые фишки в подарок или выстрадать каждую строчку кода самому.