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.