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)
}
}