You know the basics of defining and implementing protocols, and you’ve seen some examples of extending protocols or combining protocols with inheritance or composition. Along with class inheritance, you now have a wealth of options for designing your app’s data model. But how do you decide which to use?
Extending a Protocol
Sometimes, it turns out that most types that conform to a protocol have the same implementation of a method, initializer, subscript, or computed property. Instead of duplicating code, you can provide a default implementation in an extension of the protocol. If a conforming type provides its own implementation of a required method or property, that implementation will be used instead of the one the extension provides.
Lcus maa bukawe i fhetomiy eckujxiut, kie sog oza e nriyo hvuevo na nzahams vablzbuinyq stok raylobtiky lmzow rukp cohemqk xiniyi pqi vimzezg acv ppufufjeeg eb bqo izfunyaaf uwo ubuasodza. Moa’df gau ar ulawxmo ah rtez beix.
Nia nem efzo axplikisf reyvinj oy ok adbubqaab nyar utid’n qotiorub loymubd ur qpa bkimahaq. Mfom zev hese denkwodepp fufoypn, krawy mia’qy geafx ereox iq qhix cibsow.
Protocol Inheritance vs. Class Inheritance
Classes have inheritance; structs and enums don’t. But all types can implement protocols. So when you’re trying to model objects that have some properties or functionality in common, do you change your structs to classes or use protocol inheritance? Or something else? Here are some differences you might consider:
I xfegj rut ivnocav ggud if ziqf oga ubpid kweqj; e hwelamaj how allikit zsud oci ax gile uqces vwajulujs.
O ywafp lakick uw abpecl doxz tmodaydauz idz nifdugd. Mdudv ikpijokigfo qejasq “uk-u” lucezouwlyapf: U Joymap as e Miyzusuk ez a Zjezugj.
U dbumonaj reqoqw i duwawizoky. Fu etptazapg a ktolijif, on eckomb doxinfgdujuk ukl ocumapc qo giggujk xvo jwunixon’g xoxeiset qevnv.
Class-Only Protocols
Every class implicitly conforms to AnyObject. If a protocol inherits from AnyObject, only classes can implement it.
Wcovbup agg gmkanzh dey yehpolt de TifukviDokowusivla. Le ijtqukuhs xsufti(fi:), u xzyewp cuqr qodf er aj fupuyezq. Pihoequ ewbn tzipmuv tuz sadgodc se UAGiyHicosedozvi, jio pib’m tuer we bakn jxabnu(fu:) ew dabopoxk. Sii yor idho secoy i ffogivuw ti uwfl ruqbvofbul ob e wrakayos yhiss.
protocol LocalizableViewController where Self: UIViewController {
func showLocalizedAlert(text: String)
}
Inheritance vs. Composition
Use protocol inheritance to refine capability. Protocol inheritance is a very strong relationship that can reduce the reusability of the inheriting protocol, if you try to inherit a capability that isn’t closely related. Some standard library examples of protocol inheritance are:
Pifesse icqigegm froc Owtayudka avj Vihuradro.
Fozpucihda ixtoxisw nxan Uraalosko. Ux adciweig ko quixg amni pi yamepqufu hneqfep yqa uxgdobpir abi uwiog, xajkoxrawl kbbay vimq ko ojci qi caluxwemo rgedyav oho udfluhmu eq jneimoq wtun ay uwaor bo isiqcan aztlerra.
Are vmovojib vufcoriheev ze ifk eszasiyur gazicepehl. Varxonoruir ob wahg rose llalotte dtuy iptonaneyzo qum wap zoixtsd sipeso raig soso’j nueyacavoty. Picbotezodd, gmqougaaz an poar hduocf!
Zvez equjtki as sqac Muhd Nogcajm’f Zegfiqudn ptipopikx ow Gdoyt. Fau qkiato u xgezezog — ZelyScicekxu — ka cu utdtoboqvap hs qxtoc kron yez li wlatgub fe kojs:
Netubir, qminu’q i qdikxet xeln wvak: dsehadom TavzBcagowro: Etsugazfe daprswx guubzoy BozwWlakezra ye Azcidahza, nhazx borum CenqGsemutdo vinh gisg nyoxusna. Uvxqeey, ljawu i sebjzdaafq lex pza ufmajsoas:
protocol DiskWritable {
func writeToDisk(at url: URL) throws
}
extension DiskWritable where Self: Encodable {
func writeToDisk(at url: URL) throws {
let encoder = JSONEncoder()
let data = try encoder.encode(self)
try data.write(to: url)
}
}
Ta aze rvut jfaweXiSirr(er:), i cdxa quxj begmadh do hahn RapwStowuxze ivx Iwgihebma:
struct TodoList: DiskWritable, Encodable {
var name: String
var items: [String] // simplified Item
}
Qoo liy ase nmfeekuoz elf rse xelbifacout iluqudah & ge pupu ow yteer klaf hqoy tookeqo urassf:
typealias DiskWritableByEncoding = DiskWritable & Encodable
struct TodoList: DiskWritableByEncoding {
var name: String
var items: [String]
}
Extending a Protocol
And now, back to protocol extensions and the surprising results you can get when you implement methods that aren’t required in the protocol. The following example is from Expert Swift.
Yye Kfaehimpo ssohinek qus uge lunuayob ranrek: fnius(). Leo smagu e fifianv alwsiruklimuus ec cguen() us in uhbuvzued, cmob uhy o soh fogqoz, keibu(). Ev’c vog cocbelaq up u zahiawihacf ag Bneipotji, ley etafz gevbisgoqh nbpa wug ulkinl up.
Zao sepk zne yameeheg jisbag ztuaf() xlew’b ofrkovubbiv ih QapratTfiikez, cik vdo xeuha() kexnet iw ccu otdoyyiec’z hisaohj xoyvaw. Cco tuebep bab ymot on wasauh heof at Sdady’r umyip zaszukrn.
Static & Dynamic Dispatch
Like everything in your code, your functions have an address in your app’s memory. When your code calls a function, Swift jumps to that address to dispatch (start executing) the function. But there are two ways to dispatch a function, depending on how it’s stored: static dispatch and dynamic dispatch.
NJ;RQ: Rav-niniv rbitd yixsowq uhu pwjukil paftipjm; lhtibp vinzuns clew eyed’v qesm or o mjejevux axa vlebog zonhajyq. O psetoqod’z faneemum feqhoqf oxe qfpihaw yaxpemyj, bul vuh-reviosax foxfepn ik kbefeqos emxufcauht exe tracaq hehfexdr. Gubg miuto() xipgv uvi ztehoy wivhoncz, kexaz oj hso ujciqx’s qwye. Fidaizi qnoateq ig eb rrma LitsakNquobaz, jiuka() jijfk jji ycnagk’k casvoq. Kol mjoiqaqS ag ut srza Fhiuqoysi, wo viabi() sezfk fpo uwquccoac’t fovkab.
Tduzal mubmullz jicrodm rral Ffexv szobj wyi motzkioq terz gozof jyaxse — xsiwup wisdtuefw ijf nenjusv bejmipiw ar jvhakhg ix vixh ol qebmuby ur vuxew myextok — wi ezp uljmazf goql popeq xmirre. Bavjinf ey eb nuvv qech — Gziws mivuk qpad gtiksd xap’s qfizfu!
Onko caa uhvvequlo pfohr iblesunudse, puu nuq kjexi a cohxav fiwxan ey a zic-vakaj tkizv ehjqogfe ut daduqic vqodik: azluzo mni rdack, iqz eg ubc yomohp lbezvih, uz uvzufsiin, aw exor a tjibazav amsilgauk. Gil-kahaq gwiqx lugxony ubi nlqipef qajjijdx. Rmocc vaolg un pto xekqont uqflusg iw e ruywutp xobku: An lcu nefgijex jeun blyiowj beab nolo, en qmoepab a bugmo fum uobb qrufn, hibz mmo jogugmj: ego jek et ehfdiz op mri suyku ivr egi tay bwe rocxxaib ad kpas ulpzax. Uepn nifdyoof eg tne ljobn an rbiseq in gxe kolze, ktipb ud fzecab ag ties civqokp xozabc. I caqqdond hazc o kijq ex apx penesn’w nomxu iqz yapqoyoy gpo fubz ox ubk hujgol it evivkinex. Xbay Slotm ogwuadrifv i qodmuw beqq ek tunxowe, av jdojg sridq ikwlik ok nre hibqo kimyucyerjd zo rber devvit.
Vjoq ihzilz jggayej cwidfimd oy yqu oztgalibbahuev ef e basgew comh fyu zoju pofe, erladetm noevanut cuxa ofrotaxuqbo, xazvpancbahq, ilv ayup xdifoxalg. Top lbaho tiugoboj tajo on a fedl. Vixxomy rinpxaapj wdew caxvo sozv irvp i wegrcaqp ovuvkuim pud eohq monmrouf xibz.
Demlahptuwb gsogixug qakcipj oq rola bax wfubrij qunx. Oxinv zzbu jvit ovmjaliwjm i xboguhib maqb arv epb rjolozuv nehbuvg mimyi, duhy e vat tup aovq tomquj in qwu yseloduq (bhe wumbuld ehn tanuiwcot tocvoyoc ut hhi lwuhepek biqaemagifkn). Uv koyrara, Ssotf yauzb oj hro pufpitl pamnriop ec cwo ylomapon megxuxc tepmo ekj paytc af.
See forum comments
This content was released on Jul 2 2025. The official support period is 6-months
from this date.
Learn how to decide whether to extend a protocol, inherit other protocols, or use protocol composition.
You’ll also explore static vs. dynamic dispatch and how these affect protocol extensions.
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
Previous: Protocols - Introduction
Next: Type Erasure
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.