1. 接口的基本介绍
用于定义一组方法的集合,接口允许你定义对象的行为,而不必关心对象的具体实现,这有助于实现代码的松耦合和高内聚。
1.1 接口的定义
接口是一组方法签名的集合,任何类型只要实现了这些方法,就隐式地实现了该接口
1 2 3 4
| type Shape interface { Area() float64 Perimeter() float64 }
|
1.2 接口的实现
在go语言中,一个类型实现某个接口,并不需要显式声明关系。只要一个类型提供了接口所要求的所有方法,该类型就实现了该接口。
Rectangle 类型实现了 Shape 接口,因为它提供了 Area 和 Perimeter 方法。
1 2 3 4 5 6 7 8 9 10 11
| type Rectangle struct { Width, Height float64 }
func (r Rectangle) Area() float64 { return r.Width * r.Height }
func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) }
|
1.3 使用接口
接口类型的变量可以存储任何实现了该接口的实例。可以通过接口来调用方法,为无需了解具体类型。
1 2 3 4 5 6 7 8 9
| func PrintShapeInfo(s Shape) { fmt.Println("Area:", s.Area()) fmt.Println("Perimeter:", s.Perimeter()) }
func main() { r := Rectangle{Width: 3, Height: 4} PrintShapeInfo(r) }
|
在上面的例子中,PrintShapeInfo 函数接受一个 Shape 类型的参数,并调用该参数的方法。由于 Rectangle 实现了 Shape 接口,可以将 Rectangle 的实例传递给 PrintShapeInfo。
1.4 空接口
空接口(interface{})不包含任何方法,因此所有类型都实现了空接口。空接口常用于处理任意类型的数据。
1 2 3 4 5 6 7 8 9
| func PrintAnything(i interface{}) { fmt.Println(i) }
func main() { PrintAnything(123) PrintAnything("hello") PrintAnything(true) }
|
1.5 类型断言
类型断言用于将接口类型的变量转换为具体类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func Describe(i interface{}) { switch v := i.(type) { case int: fmt.Println("Integer:", v) case string: fmt.Println("String:", v) default: fmt.Println("Unknown type") } }
func main() { var i interface{} = "hello" Describe(i) }
|
2. 实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| package main
import ( "fmt" )
type Usb interface { Start() Stop() }
type Phone struct { }
func (p Phone) Start() { fmt.Println("手机开始工作。。。") } func (p Phone) Stop() { fmt.Println("手机停止工作。。。") }
type Camera struct { }
func (c Camera) Start() { fmt.Println("相机开始工作~~~。。。") } func (c Camera) Stop() { fmt.Println("相机停止工作。。。") }
type Computer struct { }
func (c Computer) Working(usb Usb) {
usb.Start() usb.Stop() }
func main() {
computer := Computer{} phone := Phone{} camera := Camera{}
computer.Working(phone) computer.Working(camera) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| type Speaker interface { Speak() string }
type Person struct { Name string }
func (p Person) Speak() string { return "Hello, my name is " + p.Name }
type Dog struct { Name string }
func (d Dog) Speak() string { return "Woof! My name is " + d.Name }
func SaySomething(s Speaker) { fmt.Println(s.Speak()) }
func main() { p := Person{Name: "John"} d := Dog{Name: "Rex"}
SaySomething(p) SaySomething(d) }
|
在这个例子中,Person 和 Dog 类型都实现了 Speaker 接口,因为它们都提供了 Speak 方法。SaySomething 函数可以接受任何实现了 Speaker 接口的实例,并调用其 Speak 方法。