package main import "fmt" // 定义一个接口 type Usb interface { // 声明两个没有实现的方法 Start() Stop() } type Phone struct { } // 让Phone 实现Usb接口的方法 func (p Phone) Start() { fmt.Println("手机开始工作。。。") } func (p Phone) Stop() { fmt.Println("手机停止工作。。。") } type Camera struct { } // 让 Camera 实现Usb接口的方法 func (p Camera) Start() { fmt.Println("相机开始工作。。。") } func (p Camera) Stop() { fmt.Println("相机停止工作。。。") } // 计算机 type Computer struct { } // 编写一个方法 Working 方法,接收一个Usb接口类型的变量 // 只要实现了Usb 接口(所谓实现 Usb 接口,就是指实现了 Usb 接口声明所有方法) func (c Computer) Working(usb Usb) { // usb 变量会根据传入的实参,来判断到底是Phone,还是camera // 通过 usb 接口变量来调用 Start 和 Stop 方法 usb.Start() usb.Stop() } func main() { computer := Computer{} phone := Phone{} camera := Camera{} computer.Working(phone) computer.Working(camera) }
说明
- 接口里的所有方法都没有方法体,即接口的方法都是没有实现的方法。接口体现了程序设计的多态和高内聚低耦合的思想。
- Golang中的接口,不需要显式的实现。只要一个变量,含有接口中的所有方法,那么这个变量就实现了这个接口。因此,Golang中没有implement这样的关键字
注意事项
- 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量
package main import "fmt" type AInterface interface { Say() } type Student struct { Name string } func (s Student) Say() { fmt.Println("Student say") } func main() { student := Student{} var a AInterface = student a.Say() }
- 接口中所有的方法都没有方法体,即都是没有实现的方法。
- 在Golang中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口。
- 一个自定义类型只有实现了某个接口,才能将该自定义类型的实例赋给接口类型。
- 只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型。
package main import "fmt" type AInterface interface { Say() } type integer int func (i integer) Say() { fmt.Println("Integer say i =", i) } func main() { var i integer = 10 var b AInterface = i b.Say() }
- 一个自定义类型可以实现多个接口
package main import "fmt" type AInterface interface { Say() } type BInterface interface { Hello() } type Student struct { Name string } func (s Student) Say() { fmt.Println("Student say") } func (s Student) Hello() { fmt.Println("Student hello") } func main() { student := Student{} var a AInterface = student var b BInterface = student a.Say() b.Hello() }
- Golang接口中不能有任何变量
- 一个接口(比如A接口)可以继承多个别的接口(比如B,C接口),这时如果要实现A接口,也必须将B,C接口的方法全部实现。
package main import "fmt" type AInterface interface { test01() } type BInterface interface { test02() } type CInterface interface { AInterface BInterface test03() } // 如果要实现 CInterface ,就需要将AInterface 和 BInterface的所有方法 type A struct { } func (a A) test01() { fmt.Println("test01") } func (a A) test02() { fmt.Println("test02") } func (a A) test03() { fmt.Println("test03") } func main() { var a A var c CInterface = a c.test01() c.test02() c.test03() }
- interface类型默认是一个指针(引用类型),如果没有对interface初始化使用,那么会输出nil
- 空接口interface{} 没有任何方法,所以所有类型都实现了空接口,即我们可以把任何一个变量赋给空接口。
接口最佳实践
package main import ( "fmt" "math/rand" "sort" "strconv" ) type Person struct { Name string Age int } type Slice []Person func (s Slice) Len() int { return len(s) } func (s Slice) Less(i, j int) bool { return s[i].Age < s[j].Age } func (s Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func main() { var slice Slice for i := 0; i < 10; i++ { person := Person{ Name: "姓名—" + strconv.Itoa(rand.Intn(100)), Age: rand.Intn(100), } slice = append(slice, person) } for _, v := range slice { fmt.Println(v) } fmt.Println("---------排序之后------------") sort.Sort(slice) for _, v := range slice { fmt.Println(v) } }