# Day 23 : Golang Interface
## interface
先舉的生活的例子來看看什麼是介面。介面可以定義特定事務的所有行為,例如我們將「寵物」當作一個介面,裡面可能有「吃飯」、「睡覺」、「玩樂」(~~怎麼跟人類很像?~~),那不管是「狗」、「貓」還是「鳥」,只要都為這些行為,就可以當做是「寵物」。因此不論是「狗」、「貓」還是「鳥」都可以被視為是「寵物」這個介面的實現。
接下來回到[A Tour of Go](https://go.dev/tour/methods/9)定義的interface如下
>*An **interface type** is defined as a set of method signatures.
A value of interface type can hold any value that implements those methods.*
在說明struct的時候,可以透過receiver function針對我們自己定義的結構體綁定method,一個interface其實就是定義該物件可以使用的全部方法(a set of method signatures)。而如果有個型別定義了完全相同的方法,就等於實現(implement)這個介面了。
## 定義與使用
但 *A value of interface type can hold any value that implements those methods* 這句話到底在說什麼,還是看不太懂,那就用寵物和行為的方式來試著瞭解看看吧。
首先定義一個Pet的interface,裡面有三個方法:Sleep()、Play()、Eat()。
接著定義一個Dog、Cat的結構體,與專屬這個型別的三個型為Sleep()、Play()、Eat()。
這時候由於Dog、Cat的三個行為讓Dog、Cat滿足Pet這個介面的規範,**Dog、Cat個型別都可以視為Pet型別**,此時在第45行將p定義是Pet介面型別,可以直接在p上使用Sleep()、Play()、Eat()方法。
最後如果不想養狗狗了(舉例而已,不要棄養)想要養貓,可以直接`p = Cat{"Orange"}`給新的值,不用透過`cat := Cat{"Orange"}`再宣告新的變數。
```go=
package main
import "fmt"
type Pet interface {
Sleep() string
Play() string
Eat() string
}
type Dog struct {
name string
}
func (d Dog) Sleep() string {
return fmt.Sprintf("I am %s, I am sleeping", d.name)
}
func (d Dog) Play() string {
return fmt.Sprintf("I am %s, I am having fun", d.name)
}
func (d Dog) Eat() string {
return fmt.Sprintf("I am %s, I am eating", d.name)
}
type Cat struct {
name string
}
func (c Cat) Sleep() string {
return fmt.Sprintf("I am %s, I am sleeping", c.name)
}
func (c Cat) Play() string {
return fmt.Sprintf("I am %s, I am having fun", c.name)
}
func (c Cat) Eat() string {
return fmt.Sprintf("I am %s, I am eating", c.name)
}
func main() {
var p Pet
p = Dog{"White"}
fmt.Println(p.Sleep()) // I am White, I am sleeping
fmt.Println(p.Eat()) // I am White, I am eating
// 棄狗養貓
p = Cat{"Orange"}
fmt.Println(p.Sleep()) // I am Orange, I am sleeping
fmt.Println(p.Play()) // I am Orange, I am having fun
}
```
## 後記
interface真的博大精深,明天再繼續介紹空介面和type assertion吧
## References
1. [A Tour of Go - interface](https://go.dev/tour/methods/9)
2. [Effective Go - interface](https://go.dev/doc/effective_go#interfaces)
3. [Day12 Go神奇的介面與斷言(Interface, assertion)](https://hackmd.io/@goFamily/Sk2bkuvqw)
###### tags: `About Go`