當前位置:
首頁 >
Go 接口
發布時間:2025/3/20
45
豆豆
#### Go 接口
上一節學習了Go 的封裝和繼承, 這一節來學習一下多態, 在Go 中多態是通過接口實現的, 所以先來學習一下接口
先來學習一個案例: package mainimport "fmt" // 定義一個接口 type USB interface {Start()Stop() } type Phone struct {} type Camera struct {} // Phone 實現USB 接口中的方法 func (p *Phone) Start(){fmt.Println("phone is working") } func (p *Phone) Stop(){fmt.Println("phone stop work") } // Camera 實現USB 接口中的方法 func (c *Camera) Start(){fmt.Println("camera is working") } func (c *Camera) Stop(){fmt.Println("camera stop work") } // 接收一個USB interface 調用接口中的方法 func Working(usb USB) {usb.Start()usb.Stop() } func main(){var phone = new(Phone)var camera = new(Camera)Working(phone)Working(camera) }
---
###### 接口的概念
interface 類型可以定義一組方法,但是這些方法不需要實現,并且interface 不能包含任何變量,當某個自定義類型需要使用接口的時候,把接口
中定義的方法實現;
基本語法:
type 接口名 interface {
方法01(參數列表) 返回值列表
方法02(參數列表) 返回值列表
...
}
方法的實現:
func (a 自定義類型) 方法01(參數列表) 返回值列表{
方法內容的具體實現
}
func (a 自定義類型) 方法02(參數列表) 返回值列表{
方法內容的具體實現
}
---
說明:
1. 接口中的***所有方法都沒有方法體***,即接口中的方法都是沒有實現的方法,體現了程序設計的多態思想;
2. Go 中的接口***不需要顯示的實現***,只要一個自定義類型實現了接口類型中的所有方法,那么這個自定義變量
就實現了這個接口;
3. 接口本身不能創建實例,但是可以指向一個實現了該接口的自定義類型的變量;
4. 一個自定義類型只有將接口中的所有方法都實現了才能稱之為實現了該接口;
5. 一個自定義類型只有實現了某個接口,才能將該自定義類型的變量賦給接口類型;
6. 自定義類型不局限于結構體, 可以是任意的自定義的數據類型;
7. 一個自定義類型可以實現多個接口;
8. 接口中不能有任何變量;
9. 接口類型是指針類型(也可稱為引用類型);
10. 空接口沒有任何方法***所有的類型都實現了空接口***,所以可以把任何一個變量都可以賦值給空接口;
11. 一個接口(A)可以繼承其它的接口(B,C...),如果要實現A接口, 需要將它繼承的接口(B,C...)也全部實現; package mainimport "fmt"type Personer interface {// 1. 接口中所有的方法都沒有方法體// 8. 接口中不能有變量// Name stringEat()Speak() } type Animaler interface {Walk() } // 接口繼承其它接口 type Childer interface {PersonerCry() } // 父結構體 type Person struct {Name string } // 繼承Person type Student struct {Person } // 繼承Person type Teacher struct {Person } // 繼承Person type Child struct {Person } // 自定義數據類型,相當于給string 類型定義一個別名 type MyData string // Student 實現接口中的方法 func (s *Student) Eat(){fmt.Printf("[Student] %s is eatting \n",s.Name) } func (s *Student) Speak(){fmt.Printf("[Student] %s is speaking \n",s.Name) } // Teacher 實現接口中的方法之一 // 只有實現了接口中的所有方法才能稱為實現了該接口 func (t *Teacher) Eat(){fmt.Printf("[Teacher] %s is eatting \n",t.Name) } // MyData 實現接口中的方法 func (m *MyData) Eat(){fmt.Printf("[MyData] is eatting \n") } func (m *MyData) Speak(){fmt.Printf("[MyData] is speaking \n") } // 7. MyData 實現多個接口 func (m *MyData) Walk(){fmt.Printf("[MyData] is walking \n") } // 11. 如果要實現Childer 接口必須要實現Personer中的方法 func (c *Child) Eat(){fmt.Printf("[Child] %s is eatting \n",c.Name) } func (c *Child) Speak(){fmt.Printf("[Child] %s is speaking \n",c.Name) } func (c *Child) Cry(){fmt.Printf("[Child] %s is crying \n",c.Name) } func main(){var p Personervar s = new(Student)// 3. 接口類型本身不能創建實例// p.Eat()// 也就是說在沒有給接口賦值前不能直接通過接口調用接口中的方法// 2. 只要實現了接口類型中所有的方法,就可以賦值給接口類型p = sp.Eat()// 4/5. 錯誤, 只有實現了接口中所有的方法才能賦值給接口類型//var t = new(Teacher)//p = t// 6. 自定義數據類型不局限于結構體var m = new(MyData)p = mp.Eat()//9. 接口是指針類型var p2 Personerfmt.Printf("%T\n",p2) // 默認值為nil//10. 可以把任何變量賦值給空接口var a interface{}var b = "hello,world"a = bfmt.Println(a)// 11.var c Childervar child = new(Child)c = childc.Cry()c.Eat() }
接口實際應用的小例子: package mainimport ("fmt""sort" ) // 自定義類型實現sort.Interface 接口 type MySort []string func (m MySort) Len() int { return len(m)} func (m MySort) Swap(i,j int) {m[i],m[j] = m[j],m[i]} func (m MySort) Less(i,j int) bool {// 先比較年i_year := m[i][6:]j_year := m[j][6:]if i_year < j_year {return true} else if i_year > j_year {return false} else {// 再比較月i_mon := m[i][3:5]j_mon := m[j][3:5]if i_mon < j_mon {return true} else if i_mon > j_mon {return false} else {// 比較日期if m[i][:2] < m[j][:2] {return true} else if m[i][:2] > m[j][:2] {return false} else {return true}}} } func main(){var strSlice = []string{// 月/日/年"08/01/2018","05/01/2019","22/06/2018","08/02/2019","22/12/2018",}// 排序前fmt.Println(strSlice)// 調用sort 包排序// 排序后的結果與預想中并不一樣sort.Strings(strSlice)fmt.Println(strSlice)// 自定義類型實現sort.Interface 中的方法,實現自定義排序sort.Sort(MySort(strSlice))fmt.Println(strSlice) }
上一節學習了Go 的封裝和繼承, 這一節來學習一下多態, 在Go 中多態是通過接口實現的, 所以先來學習一下接口
先來學習一個案例: package mainimport "fmt" // 定義一個接口 type USB interface {Start()Stop() } type Phone struct {} type Camera struct {} // Phone 實現USB 接口中的方法 func (p *Phone) Start(){fmt.Println("phone is working") } func (p *Phone) Stop(){fmt.Println("phone stop work") } // Camera 實現USB 接口中的方法 func (c *Camera) Start(){fmt.Println("camera is working") } func (c *Camera) Stop(){fmt.Println("camera stop work") } // 接收一個USB interface 調用接口中的方法 func Working(usb USB) {usb.Start()usb.Stop() } func main(){var phone = new(Phone)var camera = new(Camera)Working(phone)Working(camera) }
---
###### 接口的概念
interface 類型可以定義一組方法,但是這些方法不需要實現,并且interface 不能包含任何變量,當某個自定義類型需要使用接口的時候,把接口
中定義的方法實現;
基本語法:
type 接口名 interface {
方法01(參數列表) 返回值列表
方法02(參數列表) 返回值列表
...
}
方法的實現:
func (a 自定義類型) 方法01(參數列表) 返回值列表{
方法內容的具體實現
}
func (a 自定義類型) 方法02(參數列表) 返回值列表{
方法內容的具體實現
}
---
說明:
1. 接口中的***所有方法都沒有方法體***,即接口中的方法都是沒有實現的方法,體現了程序設計的多態思想;
2. Go 中的接口***不需要顯示的實現***,只要一個自定義類型實現了接口類型中的所有方法,那么這個自定義變量
就實現了這個接口;
3. 接口本身不能創建實例,但是可以指向一個實現了該接口的自定義類型的變量;
4. 一個自定義類型只有將接口中的所有方法都實現了才能稱之為實現了該接口;
5. 一個自定義類型只有實現了某個接口,才能將該自定義類型的變量賦給接口類型;
6. 自定義類型不局限于結構體, 可以是任意的自定義的數據類型;
7. 一個自定義類型可以實現多個接口;
8. 接口中不能有任何變量;
9. 接口類型是指針類型(也可稱為引用類型);
10. 空接口沒有任何方法***所有的類型都實現了空接口***,所以可以把任何一個變量都可以賦值給空接口;
11. 一個接口(A)可以繼承其它的接口(B,C...),如果要實現A接口, 需要將它繼承的接口(B,C...)也全部實現; package mainimport "fmt"type Personer interface {// 1. 接口中所有的方法都沒有方法體// 8. 接口中不能有變量// Name stringEat()Speak() } type Animaler interface {Walk() } // 接口繼承其它接口 type Childer interface {PersonerCry() } // 父結構體 type Person struct {Name string } // 繼承Person type Student struct {Person } // 繼承Person type Teacher struct {Person } // 繼承Person type Child struct {Person } // 自定義數據類型,相當于給string 類型定義一個別名 type MyData string // Student 實現接口中的方法 func (s *Student) Eat(){fmt.Printf("[Student] %s is eatting \n",s.Name) } func (s *Student) Speak(){fmt.Printf("[Student] %s is speaking \n",s.Name) } // Teacher 實現接口中的方法之一 // 只有實現了接口中的所有方法才能稱為實現了該接口 func (t *Teacher) Eat(){fmt.Printf("[Teacher] %s is eatting \n",t.Name) } // MyData 實現接口中的方法 func (m *MyData) Eat(){fmt.Printf("[MyData] is eatting \n") } func (m *MyData) Speak(){fmt.Printf("[MyData] is speaking \n") } // 7. MyData 實現多個接口 func (m *MyData) Walk(){fmt.Printf("[MyData] is walking \n") } // 11. 如果要實現Childer 接口必須要實現Personer中的方法 func (c *Child) Eat(){fmt.Printf("[Child] %s is eatting \n",c.Name) } func (c *Child) Speak(){fmt.Printf("[Child] %s is speaking \n",c.Name) } func (c *Child) Cry(){fmt.Printf("[Child] %s is crying \n",c.Name) } func main(){var p Personervar s = new(Student)// 3. 接口類型本身不能創建實例// p.Eat()// 也就是說在沒有給接口賦值前不能直接通過接口調用接口中的方法// 2. 只要實現了接口類型中所有的方法,就可以賦值給接口類型p = sp.Eat()// 4/5. 錯誤, 只有實現了接口中所有的方法才能賦值給接口類型//var t = new(Teacher)//p = t// 6. 自定義數據類型不局限于結構體var m = new(MyData)p = mp.Eat()//9. 接口是指針類型var p2 Personerfmt.Printf("%T\n",p2) // 默認值為nil//10. 可以把任何變量賦值給空接口var a interface{}var b = "hello,world"a = bfmt.Println(a)// 11.var c Childervar child = new(Child)c = childc.Cry()c.Eat() }
接口實際應用的小例子: package mainimport ("fmt""sort" ) // 自定義類型實現sort.Interface 接口 type MySort []string func (m MySort) Len() int { return len(m)} func (m MySort) Swap(i,j int) {m[i],m[j] = m[j],m[i]} func (m MySort) Less(i,j int) bool {// 先比較年i_year := m[i][6:]j_year := m[j][6:]if i_year < j_year {return true} else if i_year > j_year {return false} else {// 再比較月i_mon := m[i][3:5]j_mon := m[j][3:5]if i_mon < j_mon {return true} else if i_mon > j_mon {return false} else {// 比較日期if m[i][:2] < m[j][:2] {return true} else if m[i][:2] > m[j][:2] {return false} else {return true}}} } func main(){var strSlice = []string{// 月/日/年"08/01/2018","05/01/2019","22/06/2018","08/02/2019","22/12/2018",}// 排序前fmt.Println(strSlice)// 調用sort 包排序// 排序后的結果與預想中并不一樣sort.Strings(strSlice)fmt.Println(strSlice)// 自定義類型實現sort.Interface 中的方法,實現自定義排序sort.Sort(MySort(strSlice))fmt.Println(strSlice) }
個人微信公眾號上有最新文章, 歡迎關注一同交流學習
轉載于:https://www.cnblogs.com/Mail-maomao/p/11492658.html
總結
- 上一篇: Go 面向对象三大特性
- 下一篇: Go 多态