# 3.7、Golang接口 interface go语言中的接口,是一种新的类型定义,它把所有的具有共性的方法定义在一起,任何其他类型制药实现了这些方法就是实现了这个接口 语法 ```go // 定义接口 type interface_name interface { method_name [return_type] ... } // 定义结构体 type struct_name struct { } // 实现接口方法 func (struct_name_variable struct_name) method_name [return_type]{ // 方法实现 } ``` 接口示例 定义一个USB接口,有读read 写write两个方法 再定义一个电脑computer 和 手机Mobile 来实现这个接口 ```go package main import "fmt" // USB接口 type USB interface { read() write() } // Computer 结构体 type Computer struct { } // Mobile 结构体 type Mobile struct { } // Computer 实现USB方法 func (computer Computer) read() { fmt.Println("computer read") } func (computer Computer) write() { fmt.Println("computer write") } // Mobile 实现USB方法 func (mobile Mobile) read() { fmt.Println("mobile read") } func (mobile Mobile) write() { fmt.Println("mobile write") } func main() { computer := Computer{} computer.read() computer.write() // computer read // computer write mobile := Mobile{} mobile.read() mobile.write() // mobile read // mobile write } ``` > 备注: 实现接口必须实现接口中的所有方法 ## golang接口值类型接收者和指针类型接收者 示例 ```go package main import "fmt" // 定义接口 type Pet interface { eat() } // 定义结构体 type Dog struct { name string } func (dog Dog) eat() { fmt.Println("dog eat") } func main() { dog := Dog{name: "Tom"} dog.eat() // dog eat } ``` ## golang接口和类型的关系 - 一个类型可以实现多个接口 - 多个类型可以实现同一个接口(多态) ### 一个类型可以实现多个接口 示例 Music接口可以播放音乐 Video接口可以播放视频 手机Mobile实现这两个接口,即可以播放音乐,又可以播放视频 ```go package main import "fmt" // 定义接口 type Music interface { playMusic() } type Video interface { playVideo() } // 定义结构体 type Mobile struct { } func (m Mobile) playMusic() { fmt.Println("Mobile playMusic") } func (m Mobile) playVideo() { fmt.Println("Mobile playVideo") } func main() { m := Mobile{} m.playMusic() // Mobile playMusic m.playVideo() // Mobile playVideo } ``` ### 多个类型可以实现同一个接口(多态) 示例 一个宠物接口Pet,猫Cat和狗Dog都可以实现该接口 ```go package main import "fmt" // 定义接口 type Pet interface { eat() } // 定义结构体 type Dog struct { } type Cat struct { } func (dog Dog) eat() { fmt.Println("dog eat") } func (cat Cat) eat() { fmt.Println("cat eat") } func main() { dog := Dog{} dog.eat() // dog eat cat := Cat{} cat.eat() // cat eat // 声明接口变量 var pet Pet pet = dog pet.eat() // dog eat pet = cat pet.eat() // cat eat } ``` ## golang接口嵌套 示例 飞鱼,既可以飞,也可以游泳, 飞鱼接口有两个接口组成:飞Fly接口,游泳Swim接口 ```go package main import "fmt" // 定义接口 type Flyer interface { fly() } // 定义接口 type Swimmer interface { swim() } // 组合接口 type FlyFish interface { Flyer Swimmer } // 结构体 type Fish struct{} // 实现方法 func (fish Fish) fly() { fmt.Println("fish fly") } func (fish Fish) swim() { fmt.Println("fish swim") } func main() { var fly FlyFish fly = Fish{} fly.fly() // fish fly fly.swim() // fish swim } ``` ## 通过接口实现OCP设计原则 开闭原则 Open-Closed Principle 对扩展开放,对修改关闭 示例 ```go package main import "fmt" // 定义接口 type Pet interface { eat() sleep() } // 定义结构体 type Dog struct { } type Cat struct { } // Dog 实现 Pet接口 func (dog Dog) eat() { fmt.Println("dog eat") } func (dog Dog) sleep() { fmt.Println("dog sleep") } // Cat 实现 Pet接口 func (cat Cat) eat() { fmt.Println("cat eat") } func (cat Cat) sleep() { fmt.Println("cat sleep") } // 结构体 type Person struct{} // 参数既可以是Dog 也可以是 Cat func (person Person) care(pet Pet) { pet.eat() pet.sleep() } func main() { dog := Dog{} cat := Cat{} person := Person{} person.care(dog) // dog eat // dog sleep person.care(cat) // cat eat // cat sleep } ``` ## golang模拟OOP的属性和方法 golang中没有面向对象的概念,也没有封装的概念,但是可以通过而机构提struct和函数绑定来实现OOP的属性和方法 示例 Person类 - 属性: name、age - 方法:eat、sleep、work ```go package main import "fmt" // 属性 type Person struct { name string age int } // 方法 func (person Person) eat() { fmt.Println("person eat") } func (person Person) sleep() { fmt.Println("person sleep") } func (person Person) wrok() { fmt.Println("person wrok") } func main() { person := Person{ name: "Tom", age: 23, } person.eat() // person eat person.sleep() // person sleep person.wrok() // person wrok } ``` ## golang继承 通过结构体嵌套来实现继承 ```go package main import "fmt" // 定义结构体 type Pet struct { name string age int } func (pet Pet) eat() { fmt.Println("pet eat") } func (pet Pet) sleep() { fmt.Println("pet sleep") } // 定义结构体 type Dog struct { // 匿名 Pet } type Cat struct { pet Pet } func main() { dog := Dog{ Pet{name: "Tom", age: 23}, } // 匿名直接调用 dog.eat() // pet eat cat := Cat{ pet: Pet{name: "Tom", age: 23}, } // 通过属性pet 调用 cat.pet.eat() // pet eat } ``` ## golang构造函数 golang中没有构造函数的概念,可以使用函数来模拟构造函数的功能 ```go package main import "fmt" type Person struct { name string age int } func NewPerson(name string, age int) (*Person, error) { if name == "" { return nil, fmt.Errorf("name不能为空") } if age < 0 { return nil, fmt.Errorf("age不能小0") } return &Person{name: name, age: age}, nil } func main() { person, err := NewPerson("Tom", 23) if err == nil { fmt.Printf("%v\n", person) // &{Tom 23} } else { fmt.Printf("%v\n", err) } } ```