Sobes.tech
Middle

Jaký je rozdíl mezi protokoly a třídami, pokud jde o abstraktní třídy?

sobes.tech AI

Odpověď od AI

Protokol definuje smlouvu — soubor požadavků (metod, vlastností, inicializátorů), které musí typ splňující tento protokol implementovat. Protokoly nemají implementaci většiny svých požadavků. Není možné vytvořit instance protokolu.

Abstraktní třída v jazycích odlišných od Swiftu (například Java) představuje třídu, kterou nelze přímo instancovat. Obsahuje jak implementované metody (nebo vlastnosti), tak abstraktní metody, které musí být implementovány v jejích podtřídách.

Ve Swiftu neexistuje koncept abstraktních tříd v jejich tradičním pojetí. Funkcionalitu abstraktních tříd dosahuje kombinací protokolů a tříd.

Pomocí protokolu lze definovat rozhraní a poté vytvořit běžnou třídu, která odpovídá tomuto protokolu a poskytuje implementaci. Částečná implementace protokolu může být poskytnuta pomocí rozšíření (protocol extensions), ale to nezpůsobí, že protokol bude "abstraktní třídou" v čistém smyslu.

Protokol (Swift) Abstraktní třída (tradiční)
Účel Definice smlouvy (rozhraní) Definice společného chování a struktury s možností částečné implementace
Implementace Obvykle neobsahuje implementaci (kromě rozšíření) Může obsahovat jak implementované, tak abstraktní metody
Instanciace Nelze vytvořit instanci protokolu Nelze přímo vytvořit instanci abstraktní třídy
Dědičnost Shoda s protokolem (conformance) Dědičnost (inheritance)
Vícenásobná dědičnost Typ může splňovat více protokolů Třída může dědit pouze od jedné třídy (ve většině jazyků)
Ve Swiftu Hlavní forma abstrakce Neexistuje přímý ekvivalent, napodobuje se pomocí protokolů a tříd

Příklad napodobení abstraktní třídy pomocí protokolu a třídy ve Swiftu:

Protokol definující abstraktní požadavky:

// Protokol jako smlouva
protocol Drawable {
    func draw()
    var color: String { get set }
}

Třída odpovídající protokolu a poskytující implementace:

// Třída implementující protokol
class Circle: Drawable {
    var color: String

    init(color: String) {
        self.color = color
    }

    func draw() {
        print("Kreslení kruhu barvy \(color)")
    }
}

Rozšíření pro poskytnutí výchozí částečné implementace:

// Rozšíření pro poskytnutí výchozí implementace (nečiní protokol abstraktní třídou)
extension Drawable {
    func draw() {
        print("Začínáme kreslit něco barvou \(color)")
    }
}

Tímto způsobem hrají protokoly v Swiftu klíčovou roli při dosahování polymorfismu a abstrakce, nahrazují koncept abstraktních tříd v jiných jazycích.