Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

2.12 Protocols

Within the Swift language, protocols give you the ability to define a blueprint describing the features and functionalities that classes can conform to. Let’s take a look at some examples in this lesson.

Related Links

2.12 Protocols

In this lesson I'm going to introduce the concept of protocols. Now, you may be familiar with protocols in other languages referred to as interfaces. But really, the basic concept is the same. A protocol is just a blueprint of methods and properties that can be used to describe the requirements for a particular piece of functionality. Now, a protocol doesn't provide any sort of implementation for this functionality. It merely describes what it will look like. So, let's go ahead and create an example to see what that's going to look like. So, we're gonna start by creating a protocol using the protocol keyword and then specifying a name. So, this case, I'll call this MyProtocol. And then we're going to give it a body. Now within the body we're going to define what any sort of properties or methods are going to look like without actually giving them any sort of implementation. So let's just start by creating a simple property and a method and then going from there. So we'll create a property just like we would in any sort of class or structure or enumeration and we'll call this sum property. And in this case we're going to specify that this is going to be a string. And then we also have the ability within a protocol to merely describe or to define what accessibility we're going to have into this particular property. And in our case we're going to provide both a getter and a setter. So to do that, we simply specify the get keyword and the set keyword. Now, you don't have to provide both. You could maybe define this particular property as only having a getter or only having a setter, but you can do and define whatever it is that is necessary for your particular instance. And then we're also going to create a method or in our case, it's going to be a function. And we do this by describing or by defining actually the function type with the addition of having a name for this particular method. So, in our case, we're going to create a function and we'll call this some method. Now, this particular method is gonna take in any number of inputs or outputs or it could have none if we wanted. But in our case, we'll throw in a few just to, for a good measure. So we'll say parameter one, we'll call it p1, is going to be a string. And then the second parameter will be p2. And that's going to be an integer. And this is going to return a string. And that will pretty much take care of it. So in our case now, we're all done defining our protocol. We have a method and we have a property and we've defined the access. The getter is, and that, this particular property is going to have a getter and a setter. And at this particular method is going to take in a string, an int, and return a string. So how do we use this particular protocol? Well, the purpose of a protocol, as I said before, is to define some sort of functionality. Now we can create classes, structures and enumerations that will agree to implement this particular piece of functionality, or will conform to this protocol. So we'll do this with the example of a class, but like I said before, it could also be a structure or an enumeration. And in this case we'll say that this is going to be class A, and then to state that this is going to conform to my protocol, we're going to specify a colon, and then give the name of the protocol, so my protocol. So now we have to define, as you can see, we're getting these red exclamation points here that this is going to say that class A does not conform to the protocol my protocol, and this is true, it doesn't. Because these things do not exist within that class yet. So we'll go ahead and copy these, and we'll paste them into the body of our class. And now we have to give these things implementations, because now just describing this functionality by saying there's going to be a getter and a setter. Or that this particular method is going to take a string and an int and return a string is no longer enough. So now we have to give some sort of accessibility to this, or some sort of implementation. So in our case, this particular method, let's just say it's going to concatenate a string with an integer and then return the string. Or we can do that quite simply by returning p1 and we'll concatenate that using the plus symbol. And then we need to convert the integer to a string and we can do that quite simply by creating a new instance of a string by using the string initializer. And one of the inputs into this initialization method is an integer, so we can pass in p2. So now we're going to return p1 plus a stringed version of p2. So now we just have to finish defining what this property is going to look like, some property. And we could go through the process of creating a computed property since we have specified there is going to be a getter and setter and we can put some logic in there in the get. Some logic in the set or we could just state that this is really just gonna be a simple string property that's going to contain a getter and setter by default and just specify this as being an empty string to start with and this will fulfill our particular protocol. So now we can create a new instance of class a so we'll say, my a is going to be equal to a new instance of our class a type. And now, you can see that I have access in my a to go get some property, and I can set this to something, and I can also call some method. So we'll say, some property now is going to be equal to, Hello. And now, we can also call some method. And we can pass to it a string so we'll say five and the integer value of five, and now our return is gonna be the concatenation of the string five and the integer five. So there you go. Not a whole lot of interesting implementation here. But this provides you the opportunity to be able to create that contract or blueprint for some certain functionality. So where this really begins to get some, some meat and really become very useful, is let's say now I'm going to create a new class, and this one is going to be class b, but it's also going to implement my protocol. But in this case, its sum method here is going to be a little bit different in its implementation where in this case it's just going to return, Hello From Class B and that's it. And this is a perfectly valid response, and we'll call this class B, because it's still conforming to this particular protocol even though we're not using the input parameters we're still returning this. So now I could do something very similar that we did before by creating a new instance of this class. We'll just copy these. And we'll come down and make slight modifications here. This will be my b and this will be class b. And you'll quickly find that the sum property is going to be the same. Nothing's going to change there. And now when I call sum method, we're going to get the response that's coming from that particular class. No big surprise. But what really becomes interesting is if I start to create functions or other sort of functionality, that only depends on this particular protocol and doesn't care about the actual implementation, this provides us the opportunity to create code with a lot of flexibility and not be so tightly coupled to concrete implementations, which becomes very important. When you start trying to get into more object oriented concepts. So now we'll create a new function called cool funk and this is going to take in an instance and we'll call this p1 just so we can refer to it later of my protocol. And then it's going to return a string. So then our implementation of this is merely going to be returning the result from calling the sum method function and we're just gonna stick in here some pre-canned values. Hello and ten, so now we have a function that's going to take in a protocol and it's going to use that protocol to get some value out. So now I can call coolfunc and pass into it an instance of class a. And then we're going to get hello 10, but I can also call cool funk, then pass in my b, and get a completely different result. So as I said before, this starts to lend itself to things like dependency injection and loose coupling when we start to get into the world of talking about flexible code. And object oriented programming and object oriented design. This is a very important concept to the point where you should always be writing your implementations within your code against an interface or in this case a protocol to keep it as flexible as possible. And not be as concerned about the concrete implementations of those particular interfaces or protocols. This just creates much more flexible and maintainable code in the long run. So there you have it. Those are protocols within the Swift programming language.

Back to the top