持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情
接口
Go语言中的接口时一种特殊的数据类型,定义格式如下:
type name interface{
method_name() retrun_type
}
空接口
通常用空接口代指任意类型
空接口定义一个切片,内部可以存放任意类型数据
Demo01
package main
import "fmt"
//定义空接口
type Base interface {
}
func main() {
//定义一个切片,内部可以存放任意类型
list := make([]Base, 0) //简写:list:=make([]interface{},0)
//切片中添加字符串类型
list = append(list, "Sentiment")
//切片中添加整型
list = append(list, 18)
//切片中添加浮点型
list = append(list, 9.9)
fmt.Println(list)
}
结果:
[Sentiment 18 9.9]
空接口也可以作为函数的参数传入
package main
import "fmt"
func print(arg interface{}) {
fmt.Println(arg)
}
type Person struct {
name string
}
func main() {
print("Sentiment")
print("666")
print(9.9)
print(Person{name: "Sentiment"})
}
结果:
Sentiment
666
9.9
{Sentiment}
类型转换
由于接口只是代指这些数据类型(在内部其实是转换为了接口类型),想要再获取数据中的值时,需要再将接口转换为指定的数据类型。
package main
import "fmt"
func print(arg interface{}) {
tp, ok := arg.(Person)
if ok {
fmt.Println(tp)
} else {
fmt.Println("转换失败")
}
}
type Person struct {
name string
}
func main() {
print("Sentiment")
print("666")
print(9.9)
print(Person{name: "Sentiment"})
}
结果:
转换失败
转换失败
转换失败
{Sentiment}
非空接口
Demo02
package main
import "fmt"
type USB interface {
read()
write()
}
type Computer struct {
name string
}
func (c Computer) read() {
fmt.Println("this is read")
}
func (c Computer) write() {
fmt.Println("this is write")
}
func main() {
var usb USB
usb = Computer{}
usb.read()
}
结果:
this is read
类型
接口值类型
Demo03
package main
import "fmt"
type Pet interface {
eat()
}
type Dog struct {
name string
}
func (dog Dog) eat(string2 string) string {
dog.name = "Mumu"
fmt.Println(string2)
return "delicious"
}
func main() {
dog := Dog{
name: "Tana",
}
s := dog.eat("vegetable")
fmt.Println(s)
fmt.Println(dog)
}
结果:
vegetable
delicious
{Tana}
指针类型
指针类型的在调用eat()时,dog.name的值会发生改变
package main
import "fmt"
type Pet interface {
eat()
}
type Dog struct {
name string
}
func (dog *Dog) eat(string2 string) string {
dog.name = "Mumu"
fmt.Println(string2)
return "delicious"
}
func main() {
dog := &Dog{
name: "Tana",
}
s := dog.eat("vegetable")
fmt.Println(s)
fmt.Println(dog)
}
结果:
vegetable
delicious
&{Mumu}
接口和类型的关系
1、一个类型可以实现多个接口
2、多个类型可以实现同一个接口(多态)
一个类型可以实现多个接口
例:一个手机Mobile可以实现两个接口,Player播放音乐,Video播放视频
Player接口
type Player interface {
Music()
}
Video接口
type Video interface {
Video()
}
Mobile结构体
type Mobile struct {
}
Demo04
package main
import "fmt"
type Player interface {
Music()
}
type Video interface {
Video()
}
type Mobile struct {
}
func (m Mobile) Music() {
fmt.Println("this is music")
}
func (m Mobile) Video() {
fmt.Println("this is video")
}
func main() {
var music Player
music = Mobile{}
music.Music()
var video Video
video = Mobile{}
video.Video()
}
结果:
this is music
this is video
多个类型实现一个接口
例:一个宠物接口Pet,猫类型Cat和狗类型Dog都可以实现该接口(多态)
Pet接口
type Pet1 interface {
eat()
}
Dog结构体
type Dog1 struct {
}
Cat结构体
type Cat struct {
}
Demo05
package main
import "fmt"
type Pet1 interface {
eat()
}
type Dog1 struct {
}
type Cat struct {
}
func (dog Dog1) eat() {
fmt.Println("Dog eat!")
}
func (cat Cat) eat() {
fmt.Println("Cat eat!")
}
func main() {
var p Pet1
p = Dog1{}
p.eat()
p = Cat{}
p.eat()
}
结果:
Dog eat!
Cat eat!
接口嵌套
接口可以通过嵌套,创建新的接口。例:飞鱼既可以飞,也可以游泳。
飞fly接口
type fly interface {
fly()
}
游泳swim接口
type swim interface {
swim()
}
组合接口flyfish
type flyfish interface {
fly
swim
}
fish结构体
type fish struct
}
Demo06
package main
import "fmt"
type fly interface {
fly()
}
type swim interface {
swim()
}
type flyfish interface {
fly
swim
}
type fish struct {
}
func (f fish) fly() {
fmt.Println("fly!")
}
func (f fish) swim() {
fmt.Println("swim!")
}
func main() {
var f flyfish
f = fish{}
f.fly()
f.swim()
}
结果:
fly!
swim!
OCP设计原则
OCP即开-闭原则,在设计模块时,软件应该使这个模块在不被修改的前提下被扩展,即可扩展但不可以修改删除
例:接口一个Person可以有dog和cat并且有care功能
Demo07
package main
import "fmt"
type Pet2 interface {
eat()
}
type dog2 struct {
}
func (dog dog2) eat() {
fmt.Println("dog eat!")
}
type cat2 struct {
}
func (cat cat2) eat() {
fmt.Println("cat eat!")
}
type Person2 struct {
}
func (per Person2) care(pet Pet2) {
pet.eat()
}
func main() {
dog := dog2{}
cat := cat2{}
per := Person2{}
per.care(dog)
per.care(cat)
}
结果:
dog eat!
cat eat!
此时如果想再加一个pig,则不需要对原有的care方法等进行修改