Welcome back.
If something quacks moves and swims like a duck it should be a duck so we don't care about duck type
here.
We just need to know about its behavior so we can work with it without knowing anything else about the
duck type.
Let's discuss what I mean let's say there is a power socket type like this one and there are a few electrical
device types that need power the socket doesn't know anything about the devices so it can power up any
device they all need to connect the power socket to draw power so they need a common interface to the
power socket in order to draw power from it.
Here is that common interface I present to you.
The power drawer interface.
It provides a Draw method that can give power to any connected device the socket has a plug method that
accepts any device that has a Draw method.
So each device implements a Draw method to draw power from the socket.
So we say they satisfy the power drawer interface.
Now we can plug the devices to the power socket using the plug method.
Now they all are connected to the power socket the socket calls the draw method on each device and feeds
them power the socket can power up any device only with one condition.
As long as they have a draw method in other words when they satisfy the power drawer interface.
So in this example the power socket type doesn't know anything about the device types all the devices
need to draw power from the power socket.
So they all implement the power drawer interface to do that.
They implement a draw method by doing so they satisfy the interface so we can plug them to the socket
the socket powers up the devices by calling their draw method.
In summary interfaces decouple different types from each other so you can create more maintainable programs.
For example you can add more device types without changing anything of the socket type an interface
is a protocol.
It is an abstract type.
It doesn't have any implementation.
It only describes the expected behavior from a type.
For example any type that has a Draw method can satisfy the power drawer interface.
So the socket type can use any type that has a Draw method.
It's like saying I need a draw method but I don't care where it comes from.
So an interface the couples the types from each other.
It's because the types don't need to know anything about each other but the interface the opposite of
an abstract type is a concrete type.
So which types are not abstract? All the types are concrete types except the interface types.
So all the types you can see here are concrete types.
Let's take a look at an example first I'm going to delete the rest of the code from here.
I'm going to create a list variable in my store.
I sell games so I'm going to add all the games to my store.
I want my customers to see the games.
So I'm going to print them you know.
I also want to sell books but it doesn't work because Moby Dick is a book not a game.
So what should I do?
Should I create another list only for books?
Should I duplicate the list type all over again?
There should be a better way.
What does the print method need to do to print a game.
The it is a game variable.
A game has two methods print and discount but the code here only uses the print method.
Let's see who else has a print method.
The book type has a print method we know that the game type also has a print method.
So the common behavior among the game and book types is the print method we can use an interface type
to describe this behavior.
So let's create it the name of the new type can be printer because they all print something.
This is the common behavior.
Next I'm going to say that the printer is an interface type.
You know I want to create the type that only has a print method nothing more.
So I'm going to say print.
It's just a method name without code.
As you can see the printer interface is an abstract type.
I mean it doesn't contain any implementation.
It only describes the printing behavior.
Nothing more.
It's an abstract type a protocol of how to print something.
Here it says you can only satisfy me if you have a print method on you.
And I don't care about the rest.
You can implement it however you want.
Let's take a look at the interface syntax in detail here.
We declare a new printer interface type that prints something.
That's why we name it as printer with an -er suffix as a convention.
The interface keyword says that the printer is an interface type inside you type the method but without
its implementation an interface only defines the expected behavior and it doesn't care where it comes
from.
The other types need to implement the print method if they want to.
I'm going to change the type of the list instead of storing games in it,
I'm going to store printer interface values.
Yes I can do it because interface values are values so the loop variable here becomes a printer type.
Let's take a look at its methods.
There is only the print method.
This is not a coincidence.
It's because the printer interface has only one method and it is the print method.
Just like here.
Let's go back to the main function as you can see there are no more errors.
OK let's try this program.
Excellent.
It prints the games as well as the books all together.
Isn't it awesome? By changing the list to a slice of printers.
Now I can store different types in it.
Let me show you the types of elements inside the list as you can see the list contains game pointers
and book values altogether.
Even though there are different types behind the scenes.
OK let me print.
Let me comment out this printf.
Excuse me.
Okay let's say I also want to sell puzzles in my store.
To do that I'm going to duplicate the book.go file first.
I'm also going to change the book type to puzzle as you can see the puzzle has a print method.
This means that I can use it as a printer.
So let's add a puzzle to my store in the main function.
I'm going to create a new puzzle variable and I'm going to add it to my store let's try it.
Nice.
Now I can sell puzzles as well as an example.
I'm going to remove the print method from the puzzle type OK.
Let's get back to the main function.
As you can see now it doesn't work because the puzzle type doesn't have a print method anymore so it
doesn't satisfy the printer interface anymore.
That's why I cannot add it to the store slice the puzzle type is no longer a printer.
Let me take it back.
I want it to be a printer OK.
If you are coming from another object oriented programming language you can see that there is no implements
keyword in Go.
You don't have to say whether a type implements an interface or not.
It is implicit.
It is one of the powerful features of Go.
You can always add interfaces later on.
You don't have to specify them earlier.
Any type that has the methods of an interface can automatically satisfy the interface.
For example let's take a look at these types the printer interface only has a print method.
What do you think?
Which one of these types can satisfy the printer interface?
OK.
Each one of them has a print method so every one of them can satisfy the printer interface.
Now there was a discount method in the interface as well.
What about now?
Which one of these types can satisfy the interface?
This time only the game type can satisfy the interface. I mean the printer interface however the other types cannot satisfy it.
Why?
It's because they don't have a discount method.
A type can only satisfy an interface when it implements all of the methods of that interface.
The bigger the interface the weaker the abstraction.
This means that the more methods included in an interface harder to satisfy it.
That's why you might want to include fewer or even only a single method in an interface.
Let me show you one last thing.
You can also compare interface values with other values.
For example I can check whether the first item is equal to the minecraft or I can check for the last
item let's try it as you can see they both return true because they were equal all right.
It was a simple thing but I wanted to show you.
We will discuss more more more about interfaces.
No worries.
See you in the next lecture.