Protocol ve Swiftu — co to je, syntaxe a možnosti

Autor: IT Sectr Publikováno: 2026-06-17 Doba čtení: 6 min

Protocol ve Swiftu — je kontrakt definující sadu požadavků, které musí splnit každý typ, který jej přijme. Protokoly jsou základem protokolově orientovaného programování (POP) — paradigmatu doporučeného Apple pro Swift vedle klasického OOP. Podle Apple Documentation, 2026, struktury, třídy a enum mohou přijímat protokoly, což činí architekturu flexibilní a testovatelnou.

Hlavní body

  • Protocol — kontrakt s požadavky pro struktury, třídy a enum
  • Requirements zahrnují metody, vlastnosti, inicializátory a subskripty
  • Protocol Composition umožňuje kombinovat více protokolů
  • POP — protokolově orientované programování, alternativa k dědičnosti
  • Protocol Extensions přidávají výchozí implementace pro metody

Co je Protocol ve Swiftu?

Protocol — je abstraktní rozhraní, které definuje, co by měl typ umět, ale ne jak to dělá. Ve Swiftu je protokol analogií rozhraní z Javy nebo Go, ale s dalšími možnostmi.

Protokol může vyžadovat:

  • Metody instance a typu (statické)
  • Vlastnosti s určením { get } nebo { get set }
  • Inicializátory
  • Subskripty
  • Associated types (generika na úrovni protokolu)

Podle WWDC 2015 Apple představilo Protocol-Oriented Programming jako fundamentální přístup k architektuře Swift aplikací. Na rozdíl od OOP, kde dědičnost tříd vytváří rigidní hierarchie, POP nabízí kompozici protokolů. To poskytuje flexibilitu: jeden typ může odpovídat více protokolům a získávat jejich požadavky a implementace prostřednictvím extensions.

Syntaxe deklarace protokolů

Protocol se deklaruje klíčovým slovem protocol s názvem a tělem.

swift
protocol Drawable {
    func draw(context: CGContext)
    var boundingBox: CGRect { get }
}

Typ přijímá protokol přes dvojtečku za názvem:

swift
struct Circle: Drawable {
    let center: CGPoint
    let radius: CGFloat

    func draw(context: CGContext) {
        context.addArc(center: center, radius: radius, ...)
    }

    var boundingBox: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
}

Jeden typ může přijmout více protokolů oddělených čárkou: struct MyType: ProtocolA, ProtocolB. Kompilátor kontroluje, zda jsou splněny všechny požadavky každého protokolu.

Požadavky metod a vlastností

Property requirements se specifikují klíčovým slovem var a specifikátory přístupu { get } nebo { get set }.

swift
protocol UserProtocol {
    var name: String { get }
    var age: Int { get set }
    static var maxAge: Int { get }
    mutating func updateName(_ newName: String)
}

Klíčové slovo mutating v protokolu znamená, že metoda může měnit self. Struktury musí takovou metodu implementovat jako mutating, třídy ji mohou vynechat. Method requirements se specifikují s plným podpisem včetně popisků parametrů.

Dědičnost protokolů

Protocol může dědit jiný protokol a přidávat nové požadavky. To vytváří hierarchii kontraktů bez rigidního propojení s třídami.

swift
protocol Vehicle {
    var speed: Double { get set }
    func move()
}

protocol Flyable: Vehicle {
    var altitude: Double { get set }
    func takeOff()
}

Typ přijímající Flyable musí splnit požadavky obou protokolů — jak Vehicle, tak Flyable. Swift podporuje vícenásobnou dědičnost protokolů: protocol A: B, C.

Protocol Composition

Protocol Composition — mechanismus umožňující určit, že typ musí odpovídat více protokolům současně, bez vytváření nového kombinačního protokolu.

swift
func render(_ item: Drawable & Animatable) {
    item.draw(context: ...)
    item.animate(duration: 0.3)
}

Composition (&) funguje v parametrech funkcí, proměnných a generických omezeních. Kompilátor kontroluje, zda předaný typ současně vyhovuje všem protokolům. Composition se často používá ve SwiftUI: some View — to je generikum s composition.

Protocol Composition je preferován před vytvářením hierarchie dědičnosti: místo protocol A: B, C lze přímo přijmout B & C. To poskytuje flexibilitu a snižuje provázanost. Composition je obzvláště vhodný v parametrech funkcí a generických omezeních, kde je potřeba dočasně zkombinovat požadavky bez vytváření zprostředkujícího protokolu. To snižuje počet pomocných typů v kódu.

Protocol jako typ

Protocol lze použít jako typ proměnné, parametr funkce nebo prvek kolekce. To se nazývá existential type.

swift
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]

func process(drawables: [any Drawable]) {
    for item in drawables {
        item.draw(context: ...)
    }
}

Klíčové slovo any (Swift 5.6+) explicitně označuje existential. Bez any kompilátor vydá varování. Swift také podporuje some (opaque types) pro skrytí konkrétního typu za protokolem — to je standardní technika ve SwiftUI.

Typické chyby s protokoly

Při práci s protocol vývojáři často dělají několik opakujících se chyb.

  • Zapomenuté mutating — metoda v protokolu je označena jako mutating, ale struktura ji implementuje bez klíčového slova
  • Protocol as type místo generic — použití Drawable místo <T: Drawable> tam, kde je potřeba konkrétní typ
  • Circular protocol reference — protokol odkazující se na sebe přes associated type, bez správného řešení
  • Class-only protocol — použití AnyObject bez potřeby, což vylučuje struct a enum

Často kladené otázky

Čím se liší protocol od abstract class?

Protocol definuje pouze požadavky bez implementace (do protocol extensions). Abstract class může obsahovat implementaci a stav. Ve Swiftu neexistují abstraktní třídy — jejich roli plní protokoly s extensions.

Může struct přijmout protocol?

Ano, struktury, třídy a enum — všechny mohou přijímat protokoly. To je základ POP: nejste povinni používat třídy pro organizaci architektury. Struktury s protokoly poskytují sémantiku hodnot a neměnnost.

Co je associated type v protokolu?

Associated type (associatedtype) — placeholder pro typ, který si implementující typ určuje sám. Příklad: Collectionassociatedtype Element. To je generikum na úrovni protokolu.

Lze omezit protokol pouze pro třídy?

Ano, přidejte dědičnost od AnyObject: protocol MyProtocol: AnyObject. Pak pouze třídy mohou přijmout tento protokol. To je užitečné pro weak reference a delegáty.

Jak zkontrolovat shodu s protokolem za běhu?

Použijte is pro kontrolu a as? pro převod: if let drawable = item as? Drawable. To funguje pouze pro protokoly bez associated types.

Shrnutí

  • Protocol — kontrakt pro metody, vlastnosti, inicializátory a subskripty
  • Class, struct, enum — všechny typy mohou přijímat protokoly
  • Dědičnost protokolů vytváří hierarchii kontraktů bez rigidního propojení
  • Protocol Composition (&) kombinuje protokoly bez dědičnosti
  • Existential types (any) a opaque types (some) — dva způsoby práce s protokoly
  • POP doporučený Applem jako alternativa ke klasické dědičnosti tříd
  • Protocol Extensions umožňují přidávat výchozí implementace

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také