Protocol concept
Protocol is understood as a blueprint containing properties, methods and other declarations to perform a certain task, features. Protocol can be implemented by a Class, Struct or Enum.
When implementing a Protocol , we will have to declare and redefine the properties and methods included in that Protocol.
Protocol declaration syntax
Protocol declaration syntax is relatively similar to Class, Struct or Enum
1 2 3 4 5 | <span class="token comment">// Khai báo Protocol</span> <span class="token keyword">protocol</span> <span class="token builtin">Code</span> <span class="token punctuation">{</span> <span class="token comment">// Nội dung Protocol khai báo trong đây</span> <span class="token punctuation">}</span> |
Want Struct, Class or Enum implement one or more Protocol, we declare as follows
1 2 3 4 5 6 | <span class="token keyword">protocol</span> <span class="token builtin">Eat</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">struct</span> <span class="token builtin">Dev</span> <span class="token punctuation">:</span> <span class="token builtin">Code</span> <span class="token punctuation">,</span> <span class="token builtin">Eat</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> |
In case of implementing implementations for a Subclass, we have to put the name of Superclass (Superclass) before the name of the Protocol
1 2 3 4 5 6 | <span class="token keyword">class</span> <span class="token class-name">Human</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Dev</span> <span class="token punctuation">:</span> <span class="token builtin">Human</span> <span class="token punctuation">,</span> <span class="token builtin">Code</span> <span class="token punctuation">,</span> <span class="token builtin">Eat</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> |
Declare properties and methods in Protocol
Properties in Protocol
To declare properties in Protocol, there must be enough 3 elements
- Attribute name
- Datatypes
- The state of an attribute (get – get set)
1 2 3 4 5 | <span class="token keyword">protocol</span> <span class="token builtin">Code</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> experience <span class="token punctuation">:</span> <span class="token builtin">Int</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> language <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token keyword">set</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Note: The attribute in Protocol must be declared as a var . Because Protocol defaults on these properties as Computed Properties, it is not possible to declare let and must declare a state of get or get set.
1 2 3 4 5 6 | <span class="token keyword">protocol</span> <span class="token builtin">Code</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> level <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token punctuation">}</span> <span class="token comment">// Error: 'let' declarations cannot be computed properties </span> <span class="token keyword">var</span> experience <span class="token punctuation">:</span> <span class="token builtin">Int</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> language <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token keyword">set</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Protocol supports keyword “static” to declare attribute of Type instead of Instance (Protocol does not support keyword “class” )
Method in Protocol
Method declaration is similar to Class and Struct but has no {} and no content.
The Protocol supports both Type Function ( “static” declarations) and Instance Function
Note: Protocol does not allow using constants as parameters for methods
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">enum</span> <span class="token builtin">FeelHungry</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> yes <span class="token keyword">case</span> no <span class="token punctuation">}</span> <span class="token keyword">protocol</span> <span class="token builtin">Human</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token keyword">func</span> <span class="token function">talk</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">eat</span> <span class="token punctuation">(</span> <span class="token number">_</span> feelHungry <span class="token punctuation">:</span> <span class="token builtin">FeelHungry</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">eat2</span> <span class="token punctuation">(</span> <span class="token number">_</span> feelHungry <span class="token punctuation">:</span> <span class="token builtin">FeelHungry</span> <span class="token operator">=</span> <span class="token punctuation">.</span> yes <span class="token punctuation">)</span> <span class="token comment">// Error: Default argument not permitted in protocol method </span> <span class="token punctuation">}</span> |
If Struct or Enum implement Protocol, but when defining methods, we want to change its properties, we will have to declare the keyword “mutating” (Do Struct and Enum are reference values )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">protocol</span> <span class="token builtin">Activities</span> <span class="token punctuation">{</span> <span class="token keyword">mutating</span> <span class="token keyword">func</span> <span class="token function">eat</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">enum</span> <span class="token builtin">State</span> <span class="token punctuation">:</span> <span class="token builtin">Activities</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> hungry <span class="token keyword">case</span> notHungry <span class="token keyword">mutating</span> <span class="token keyword">func</span> <span class="token function">eat</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">switch</span> <span class="token keyword">self</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token punctuation">.</span> notHungry <span class="token punctuation">:</span> <span class="token function">print</span> <span class="token punctuation">(</span> <span class="token string">"Don't need to eat"</span> <span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token punctuation">.</span> hungry <span class="token punctuation">:</span> <span class="token function">print</span> <span class="token punctuation">(</span> <span class="token string">"Eat something"</span> <span class="token punctuation">)</span> <span class="token keyword">self</span> <span class="token operator">=</span> <span class="token punctuation">.</span> notHungry <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Optional Protocol
When a Protocol contains so many methods that do not want those Protocol implementers to declare everything, we use the Optional Protocol. There are 2 ways to declare Optional Protocol
Method 1: @objc optional
Declare the @objc optional
keyword before the attribute, method, and ” @objc ” before the Protocol declaration. This declaration returns the protocol to the Objective-C compiler, so only the class can implement this Protocol
1 2 3 4 5 6 7 8 9 10 11 | <span class="token atrule">@objc</span> <span class="token keyword">protocol</span> <span class="token builtin">OptionalMethodsProtocol</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">mustImplement</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token atrule">@objc</span> <span class="token keyword">optional</span> <span class="token keyword">var</span> <span class="token function">haveNotImplement</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">SomeClass</span> <span class="token punctuation">:</span> <span class="token builtin">OptionalMethodsProtocol</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">mustImplement</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">// Không cần khai báo lại haveNotImplements() do đó là optional </span> <span class="token punctuation">}</span> |
Method 2: Extention Protocol
This is an optional protocol that is suitable for both Struct, Enum and Class.
Note: Stored Properties cannot be declared
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">protocol</span> <span class="token builtin">OptionalProtocol</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">mustImplement</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">extension</span> <span class="token builtin">OptionalProtocol</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">haveNotImplement</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">struct</span> <span class="token builtin">SomeStruct</span> <span class="token punctuation">:</span> <span class="token builtin">OptionalProtocol</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">mustImlement</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">// Không cần khai báo lại haveNotImplements() do đó là optional </span> <span class="token punctuation">}</span> |
Application of Protocol
- Protocol can be used as a data type
- Use in Delegate Design Pattern (Used to “capture events”, transfer data between ViewController “)
- Expand object
- Used in many standard Swift libraries (Equable, Comparable, Hasable, Int, …)
- POP Programming (Protocol Oriented Programming)