Welcome back.
In this lecture I'm going to show you what happens when you embed a type with methods to another type
Here is a little warning before you continue.
If you get confused at any moment of this lecture please check out the struct embedding lecture in the
structs section.
After that everything will be clear.
Let's take a look at these types.
They all have almost the same set of fields and methods they all use the title and price fields and
they all use the print methods only the game and toy types have a discount method.
I might want to make a discount for every type of product.
So I'm going to add a discount to the book and puzzle types as well.
Now all the types almost look alike.
The only difference between them is the published field of the book type.
But that's okay.
It can stay.
Let's invent another type with these common fields and methods.
Okay great.
Every product has a title and price fields.
Also a print and discount methods.
Let's embed the product type to each product type.
Now all the types here embed a product type.
So the book puzzle game and toy types can use the fields and methods of the product type as if they're
on let's implement this in the coding editor.
First, I'm going to open the toy type here.
I'm going to copy everything then I'm going to create a new file for the product type here.
I'm going to replace the toy word with the product word.
Let's also change the receivers to P. Short for a product. When the other types embed this type,
all these fields and methods will be available to them so they will be able to use them as if they're
on.
That's it.
Now it's time to embed the product type.
Let's start with the book type.
The new product type already has a title and price so I'm going to delete them from the book type.
Instead, I'm going to embed the product type. The product type has a print method as well.
Should I remove it from here?
No, I shouldn't because the book type needs to print a publishing date but the product type doesn't
know how to print it.
Instead, I'm going to call the print method of the product type as you can see you can run the method
of an embedded type as well. The product type will print the title and the price of the book.
It's because it's been embedded in this book type.
So I'm going to remove these fields from here. For now, I am only going to add a tab character here.
You will see what it looks like in a minute.
One last thing I need to do here the product type uses pointer receivers.
It's better to be consistent.
So let's change the book type method to pointer receivers as well.
Let's continue with the game type. The product type has all the fields and methods of this type.
So let's remove all of them.
Instead I'm going to embed the product type.
That's all.
Don't worry though.
Thanks to the embedding the game type will have the fields and methods of the product type.
Let's do the same thing for the puzzle type.
Let's remove all the fields and methods.
I'm going to embed the product type instead.
Lastly let's go to the toy type.
Let's do the same thing again.
So I'm going to remove all the fields and methods and embed the product type.
Okay we're almost ready.
However as you can see there is a lot of errors in the main function.
It's because since I embedded the product type I need to change these composite literals first.
I'm going to remove all the field names this step wasn't necessary but I'm trying to keep the code
concise.
OK.
Now I'm going to embed the fields using the product type.
This second step was necessary because all the types embed the product type there is still an error.
Let me tell you why.
As you know the print method on the product type uses a pointer receiver.
So I need to take the addresses of the book and puzzle values.
So let's go to the main function here.
I'm going to make the book and puzzle types pointer values like so there is only a single error left.
Remember the third book doesn't have a publishing date. Since I'm not using the field names,
I need to pass the published field value myself. So, I'm going to pass a nil value here.
Nice.
Errors are gone.
Let's run the program.
Good.
It works.
However, the publishing dates don't look cute.
I will fix them afterward.
Don't worry about them for now.
OK.
As an example let's create a toy variable as you can see the toy doesn't have any fields or methods.
However, when I list its fields and methods, there happens to be many of them. It's because there are the
product types' fields and methods.
The toy type has embedded all of them automatically.
Let me show it.
I'm going to print it like this.
As you can see this toy value only contains a product value the toy value doesn't have any fields but
a product field. Every field and method comes from the product type.
Let's take a look at a book value instead.
It has a product field that contains title and price fields.
However, the book also has a publishing date field. So, it takes only some part of its fields from the
product the book type has a print method.
It embeds a product type and the product has a print method as well.
When you print a book, Go will run the book type's print method first.
So the book type as the parent type takes priority.
The book can also run the print method of the product.
So the product print can use the title and price fields to print itself.
Lastly, let's take a look at the list type.
Since I embed the product type in all the product types, I can change
this discount method. I mean I don't have to check for the discount method all the product types already
have a discount method.
So I'm going to call the discount method directly like this but it doesn't work.
It's because the list can only work with printer interface values but the printer interface doesn't
have a discount method to solve this problem.
I'm going to add a discount method to the printer OK.
The error is gone but the printer interface not only prints,
it also discounts. So it is better to change its name to item.
Now the list type can store any type that has a print and a discount method.
As I said, all the products have these methods already. So, they satisfy the item interface
now.
Let's run this program. As you can see it still works.
This is one of the benefits of implicit interfaces.
The book puzzle game and toy types don't know anything about the item interface.
They satisfy it implicitly.
That's why changing the interface from printer to item didn't break anything. Congrats!
This was the interfaces.
See you in the next lecture.