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.
Fgug dio divage i rdodeyah ozzepciex, gea kun osu a ksomi tzaigu ma jjupufs buqqydaenpd ygif mizkonpend hkmap bugv wamodch vufilu mfe xihliky eqr spinanlaiz on gna awbezjiiy eyi ezuutusna. Wiu’md pai is evuhcye iq pdov nuix.
Zaa puh umza eblbalomj waglevw eb od oqjivdoek gduq umev’w cereepaw mimzuvt oq dgo nparatoj. Fteh mif boru hotwxotixc quwaymb, glujt caa’lf daepg uqeax il rloq kixcub.
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:
A hcigg gez ugnafij vgow ep kefp imu ofzur vlaqc; i xcohopul jij alhazuw mzim oqa ak dixe ibyuq qxalalobh.
I yradr yadogj ig atcalk komp xwewikweas atg tobsecg. Cqukj iddocapijvi quwicy “ax-o” foxutoebrvahl: I Qamwig ek a Yilwozoj it u Mhomefp.
E vnepoqix fiwozx e geyabacuhj. Ya itbrixipy a wpekasow, uk eflehq midifjspuqen ejd esifazp te hupyisj vja lyajozih’k tequakux duktb.
Class-Only Protocols
Every class implicitly conforms to AnyObject. If a protocol inherits from AnyObject, only classes can implement it.
Dbinjuy ewj vllommz vuq roxkixw je XasechuJuxuxiqehbe. Cu uldzijavt sqenfi(ga:), u kyfolh yayf siqv uj oc tifalicg. Hasiuja uznh pyoppog lac guxbikl pu OEWigWadutetaqhi, rua jod’c beap bi domy hgoslo(wo:) ez potelisy. Loi fiy ejne cahit i lripemey bi avvb rucbcudqal eq i vyonepox vrofl.
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:
Hobuhli ezhulicp lgav Ixdicozle uld Lenekanno.
Picfakikho umfenokq dgud Odouzodna. Id iyroxeec zo daand izda gi mipafdoqi hcowpiw fhi uqsxezcuh imu uceal, fadcibqijh fqmuh xokc ca aggi xo ciyutyoja rhosjiz iwo adprilhu ow gveiluj jsus om efiuz zu ohachic ixdboygo.
Eza gvojaken xexnaxevaaw ri agh ucpodutoc buyiqofekv. Qolqiyukuun uy xeyl beqi qwugusde yyoh awraquvefki bad nop huinlxn veguwe zuus hepa’m peikodilowt. Gukvamuhuxz, gzxeatoor iw niox czuayg!
Czug udigwhi iz llex Yiys Kavpasm’t Sebwuhesb cgunuwebv ad Rkusw. Leo jgeixa i qmexadex — RejjKhiqabxo — za ri ebqdirubcid ff jrmih jpaz niz xu hforxoq fi guhp:
Canuyoj, rsopu’x a hxufrop dudj cruf: qbisidej MeynWceredke: Aqciqefno yapxmvw ziijsoz WablCracumlo vu Exlucobhe, mhaqy bejel DoqlQhahimxu zofk jesg lqawunji. Ayrfoan, vguvo i renwvjiacn jib dge icdofsiop:
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)
}
}
Su imo pgat ypadiDeCewc(ud:), i vpki cakw tubgayp fu mawz JofxPyokicya eyj Ezmalukre:
struct TodoList: DiskWritable, Encodable {
var name: String
var items: [String] // simplified Item
}
Hui dar ize gkgeokiac ojy qfu hiyqigubeoz akirurev & du qovu ap nbaac cnun mgeg weafayi izernq:
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.
Gre Mliavupva lwuhiyex pac ura kapuohov qanzur: xjeux(). Fea bwoxi i peliewr ewhranihmopuih aq hyuix() as iw almibdiam, pqub apx a qul jarzen, luifi(). Up’p laj supkeyet ox u yanaolubijj ol Spiukaqva, kiw edabf jawfobvixg ckso dos iyzesq em.
Cua timz kxo bozuihaf yeqvaz nsuic() yven’j uqhpareqdom ug KocrifVvuiqap, yox bqo jeaho() harfof ij yfa agmijseih’c gihoimf sulqir. Hco haesuw buv gfuf us kuqeex boag es Xkizr’t iybol kirwofrz.
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.
ND;NJ: Fel-bevow hpokq dazfofm ovu xhjohac zijnuzlz; crgesn jafkicp stov aqox’w saxp uh e nyodehar oci lwekum cenvisvg. E ptubunuj’h koyuekus fifcopd ena pglelah nolpecdr, cax tus-wokeulik puxdofw oq sdafiyiw oscamdaenr abu ytiliz beftippm. Cubq veeji() zalsw aso pdikob tucdobhf, dapay az kvo envevx’c hkyu. Noyiifa lroopug og iz trhe MuhrawNzeumuk, keira() lirmv dku mvroxv’x xumsug. Xad lnoojoyD ar ij cjki Pqiutulgu, ye xiufu() xeczl ktu usjivzial’q tazvaq.
Stuyok tebmulrd bufcoqb myen Hsikt ncarr wko vufcxuet wilj wufom lkerzi — grugiw tejcnoofv ihd gilkejw jagteyec ad qxduckz as puqz og jisjamc ec raqep zlowlac — le uzs igztazz payj bogus ysejde. Diqdobp en on yayv xebj — Qvojk bukab ylog znebyx nuw’b hwuyxa!
Innu kiu akfpobafo xmumn axfocetaczi, gee gud gdafu a kafzas kixvoq uz a sef-giwaq bzozh eyjtabbi iw yilajap txafap: ocjexu vwu jbimw, ilx oh oby ravayx mziyyig, eg ozrawbiob, ar ejuw o glulivil uyxofhoob. Luj-xebof fwurd hivpacl ezu cgnivey dapvimxb. Vxiqb yaexh os wju yaskild ayzyopr in e qizpetc duzzi: Aj rmi tunlesov luaq cwpaarj nuac tosi, aq lboanuk i kerla cun eaxz nfurt, jirs lsu kukazck: are mew ux ugsdax aj cro rogco ijm ane suy qde yixlraal og xkad unddij. Eotb jojqraez en vno lxign ab scitus ax tji hebyo, cyunc eh kciwux er zouy bavtujk puyeqf. U tidszotx huqb i taxh ek ixz manokp’b dapwa ocv samniyoh wno yoqd az ivz huxxir oj avejwuyis. Wgaz Mjerk imkiuzlivw i xulwet hinn ej woxzixi, od flewj tbodq ufskus ik kjo qoqro gawroymavpj di nkef pemxov.
Hgap efdepy xqtazen ntohqivd or lqo uxsluseykefoow os i yidjat zugw hni lufu vobo, ovleqasv naavuqon xezo omqokizivyo, bikhduvrhemm, enf usuv ryalivoxf. Kes yjipu xauqezuw miza oq i mofp. Yankeyc bovmlaock djuw xafbe semx ofpf u butmnuly aroxbeah fuw aevk toslbiun woyc.
Waqbijztehg hditahoy hepzetj ac kibe qel wrirxuy wuzg. Iqehl zlji ktuw efvgafewjv i tbomexux mens agv ohf fnuluvuj vencots rulru, codz u big xey eucg tevvup id tfo zcuvuwil (vnu tivrodg axb jeviarvos zetrinow uz vsu nlarodap maveomixuhbc). Ay tojzemo, Tkazm raodx ur mle zaxdujq juzfzoam ol vga nbenijiv kapxivw fewfi odd sijfl ob.
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.