Go笔记(十二):接口
1、接口的声明
Go语言中的接口是一种新的类型定义,拥有将具有共性的方法定义在一起的特性。任何其他类型只要实现了这些方法就是实现了这个接口。
语法详情如下:
/* 定义接口 */ type interface_name interface { method_name1 [return_type] method_name2 [return_type] method_name3 [return_type] ... method_namen [return_type] } /* 定义结构体 */ type struct_name struct { /* variables */ } /* 实现接口方法 */ func (struct_name_variable struct_name) method_name1() [return_type] { /* 方法实现 */ } ... func (struct_name_variable struct_name) method_namen() [return_type] { /* 方法实现*/ }
示例代码如下:
1 package main 2 3 import "fmt" 4 5 // 不同结构体的接受者 6 type Plane struct { 7 name string 8 } 9 10 // 要实现某个接口,必须实现该接口的所有方法 11 type Bird struct { 12 name string 13 color string 14 } 15 16 // 定义接口 17 type Flying interface { 18 // 定义接口方法 19 takeoff() 20 descend() 21 } 22 23 // 方法的接收者是 Bird 24 func (bd Bird) takeoff() { 25 fmt.Printf("bd.name: %v, bd.color: %v take off \n", bd.name, bd.color) 26 } 27 func (bd Bird) descend() { 28 fmt.Printf("bd.name: %v, bd.color: %v descend \n", bd.name, bd.color) 29 } 30 31 // 方法的接收者是 Plane 32 func (pe Plane) takeoff() { 33 fmt.Printf("pe.name: %v takeoff \n", pe.name) 34 } 35 func (pe Plane) descend() { 36 fmt.Printf("pe.name: %v descend \n", pe.name) 37 } 38 39 func main() { 40 bd := Bird{"猫头鹰", "黑色"} 41 bd.takeoff() 42 bd.descend() 43 fmt.Printf("--------------\n") 44 pe := Plane{"爱国者"} 45 pe.takeoff() 46 pe.descend() 47 }
2、接口接受者类型
2.1、值类型
1 package main 2 3 import "fmt" 4 5 // 定义接口 6 type Animal interface { 7 eat(name string) 8 } 9 // 声明结构体 10 type Cat struct { 11 name string 12 } 13 // 值类型接受者 14 func (cat Cat) eat(name string) { 15 cat.name = cat.name + "-v" 16 fmt.Printf("cat.name: %v eating \n", cat.name) 17 } 18 19 // 接口值类型接受者 20 func main() { 21 cat01 := Cat{ 22 name: "pter", 23 } 24 fmt.Printf("cat01: %v\n", cat01) 25 cat01.eat(cat01.name) 26 fmt.Printf("cat01: %v\n", cat01) 27 }
2.2、指针类型
1 package main 2 3 import "fmt" 4 5 // 定义接口 6 type Animal interface { 7 sleep(name string) 8 } 9 // 声明结构体 10 type Cat struct { 11 name string 12 } 13 14 // 指针类型接受者 15 func (cat *Cat) sleep(name string) { 16 cat.name = cat.name + "-p" 17 fmt.Printf("cat.name: %v sleep \n", cat.name) 18 } 19 20 // 接口指针类型接受者 21 func main() { 22 cat := Cat{ 23 name: "pter", 24 } 25 fmt.Printf("cat: %v\n", cat) 26 cat.sleep(cat.name) 27 fmt.Printf("cat: %v\n", cat) 28 }
3、接口与类型的关系
3.1、一个类型实现多个接口
1 package main 2 3 import "fmt" 4 5 // 有声音的接口 6 type Audible interface { 7 playMusic() 8 } 9 // 可观看的接口 10 type Viewable interface { 11 viewMovie() 12 } 13 // 结构体 14 type Computer struct{} 15 // 接收者为 Computer 的方法 16 func (c Computer) playMusic() { 17 fmt.Println("play music...") 18 } 19 func (c Computer) viewMovie() { 20 fmt.Println("view movie...") 21 } 22 23 // 一个类型实现多个接口 24 func main() { 25 computer := Computer{} 26 computer.playMusic() 27 computer.viewMovie() 28 }
3.2、多个类型实现同一接口
1 package main 2 3 import "fmt" 4 5 type BC struct { 6 kind string 7 } 8 type BM struct { 9 kind string 10 } 11 type Car interface { 12 run() 13 } 14 func (m BM) run() { 15 fmt.Println(" 宝马在高速行驶 ") 16 } 17 func (c BC) run() { 18 fmt.Println(" 奔驰在高速行驶 ") 19 } 20 21 func main() { 22 m := BM{} 23 c := BC{} 24 m.run() 25 c.run() 26 }
3.3、接口嵌套
1 package main 2 3 import "fmt" 4 5 // 爬行的 6 type Crawling interface { 7 crawl() 8 } 9 // 游泳的 10 type Natatorial interface { 11 swim() 12 } 13 // 接口组合 14 type AmphibiousAnimals interface { 15 Crawling 16 Natatorial 17 } 18 // 定义结构体 19 type tortoise struct{} 20 // 实现接口方法 21 func (t tortoise) crawl() { 22 fmt.Println(" tortoise crawl ") 23 } 24 // 实现接口方法 25 func (t tortoise) swim() { 26 fmt.Println(" tortoise swim ") 27 } 28 29 func main() { 30 t := tortoise{} 31 t.crawl() 32 t.swim() 33 }
4、模拟接口设计原则
面向对象的OCP设计原则,是可复用设计的基石,"开闭"原则(Open-Closed Principle),对拓展是开放的,对修改是关闭的。
Go语言虽不是面向对象的语言,但可以模拟实现此原则。
1 package main 2 3 import "fmt" 4 5 // ocp设计原则 6 type Pet interface { 7 eat() 8 } 9 type Dog struct{} 10 func (dog Dog) eat() { 11 fmt.Println(" dog eat") 12 } 13 14 type Person struct{} 15 // 利用多态,设计java中的向上类型转换 16 func (per Person) care(p Pet) { 17 p.eat() 18 } 19 // 新增一个宠物,无需修改原有代码,只需做拓展即可 20 type Pig struct{} 21 func (pig Pig) eat() { 22 fmt.Println(" pig eat") 23 } 24 func main() { 25 dog := Dog{} 26 per := Person{} 27 per.care(dog) 28 29 pig := Pig{} 30 per.care(pig) 31 }