<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Protocols on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/protocols/</link><description>Recent content in Protocols on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Tue, 16 Aug 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/protocols/index.xml" rel="self" type="application/rss+xml"/><item><title>Protocols</title><link>https://blog.iankulin.com/protocols/</link><pubDate>Tue, 16 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/protocols/</guid><description>&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/protocoldroid-swe.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;The evolution of structs into class-like things that can hold properties &lt;em&gt;and&lt;/em&gt; methods in Swift raised in my mind &amp;ldquo;what about inheritance?&amp;rdquo; - but no: structs in Swift can not use inheritance.&lt;/p&gt;
&lt;p&gt;Swift classes implement inheritance, but only from one class; there&amp;rsquo;s no multiple inheritance. Protocols neatly address both these concerns to a large extent, but perhaps before we look at how they work, we should have a brief diversion into inheritance in C++.&lt;/p&gt;
&lt;p&gt;#include &lt;iostream&gt;&lt;/p&gt;
&lt;p&gt;class Shape {
public:
int sides;
};&lt;/p&gt;
&lt;p&gt;class Drawable {
public:
virtual void draw() {}
};&lt;/p&gt;
&lt;p&gt;class Square : public Shape, public Drawable {
public:
Square(){
sides = 4;
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; void draw() {
 std::cout &amp;lt;&amp;lt; &amp;quot;■&amp;quot; &amp;lt;&amp;lt; std::endl;
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;int main() {
Square square;
square.draw();
return 0;
}&lt;/p&gt;
&lt;p&gt;In the code above, there&amp;rsquo;s two classes &lt;em&gt;Shape&lt;/em&gt; and &lt;em&gt;Drawable&lt;/em&gt;. You could regard &lt;em&gt;Drawable&lt;/em&gt; as an &lt;em&gt;interface&lt;/em&gt; if you&amp;rsquo;re coming from Java world (because the method draw() is marked &lt;em&gt;virtual&lt;/em&gt; - there&amp;rsquo;s no implementation). The class &lt;em&gt;Square&lt;/em&gt; inherits from both those classes - it&amp;rsquo;s a new class that is a &lt;em&gt;Shape&lt;/em&gt;, but is also &lt;em&gt;Drawable&lt;/em&gt;. (Line 15 above)&lt;/p&gt;
&lt;p&gt;Perhaps in this program there&amp;rsquo;s other items such as images or text - ie not shapes which might also inherit from &lt;em&gt;Drawable&lt;/em&gt;. Elsewhere, we could have a method that had to draw a collection of things - it doesn&amp;rsquo;t care what the items are, as long as they are &lt;em&gt;Drawable&lt;/em&gt; - they have to implement the &lt;em&gt;Draw&lt;/em&gt;() method.&lt;/p&gt;
&lt;p&gt;Swift addresses most of these needs with Protocols. A protocol defines a set of properties and methods. Then a struct, class, or even enum can &lt;em&gt;conform&lt;/em&gt; with this protocol - they contain the same properties, and are required by the compiler to implement the methods from the protocol.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the Swift equivalent of the C++ above:&lt;/p&gt;
&lt;p&gt;protocol Shape {
var sides: Int { get set }
}&lt;/p&gt;
&lt;p&gt;protocol Drawable {
func draw()
}&lt;/p&gt;
&lt;p&gt;struct Square: Shape, Drawable {
var sides: Int = 4
func draw() {
print(&amp;quot;■&amp;quot;)
}
}&lt;/p&gt;
&lt;p&gt;let square = Square()
square.draw()&lt;/p&gt;
&lt;p&gt;So, that&amp;rsquo;s cool, but not amazing. The power is really that now we can write a function that takes anything that&amp;rsquo;s Drawable as if it was a real type. To wit:&lt;/p&gt;
&lt;p&gt;class IanClass: Drawable {
func draw() {
print(&amp;ldquo;Ian&amp;rdquo;)
}
}&lt;/p&gt;
&lt;p&gt;func drawAThing(_ thingToDraw: Drawable){
thingToDraw.draw()
}&lt;/p&gt;
&lt;p&gt;let squareStruct = Square()
let ianClass = IanClass()&lt;/p&gt;
&lt;p&gt;drawAThing(squareStruct)
drawAThing(ianClass)&lt;/p&gt;
&lt;p&gt;So the function &lt;em&gt;drawAThing()&lt;/em&gt; is happy to draw anything, as long as it conforms with the Drawable protocol by implementing the draw() method. It doesn&amp;rsquo;t even matter what it is - as in this example where we&amp;rsquo;ve passed it a struct on one occasion, and a class on another.&lt;/p&gt;
&lt;p&gt;Protocols are a great example of Swift being flexible while being type-safe.&lt;/p&gt;</description></item></channel></rss>