接口
1 接口类型作为函数的传入参数时,里面只能调用接口的方法,接口绑定的对象的方法是无法调用的,
package main import "fmt" type cat struct { name string } type Ilife interface { cry() } func implement_Ilife(life2 Ilife) { life2.cry() // 接口对象只能调用接口中的方法,接口绑定的对象的方法是无法调用的, //life2.run() } func (c *cat) cry() { println("喵喵喵") } func (c *cat) run() { println(c.name + " is running") } func main() { c := cat{name: "Tom"} fmt.Println(c) // 由于cry接受的参数是指针变量,所以这里必须是&c才行, // 注意是地址可以赋值给普通变量,普通变量无法赋值给地址变量, implement_Ilife(&c) }
2 当结构体A内的属性B实现了接口I时,结构体A同时也实现了接口I,
package main import "fmt" type voice struct { } type cat struct { voice name string } type IRun interface { run() } type ICry interface { cry() } func (c *cat) run(){ println(c.name + " is running") } func (v *voice) cry(){ println("喵喵喵") } // 当结构体A内的属性B实现了接口I时,结构体A同时也实现了接口I, func main() { c := cat{voice:voice{}, name:"Tom"} var i IRun i = &c // 这里必须要取地址, i.run() // 注意返回的m是绑定了i底层对象的实现了ICry的接口的一个副本, if m, yes := i.(ICry); yes{ println("i下的voice实现了ICry接口,所以i也实现了该接口,") fmt.Println(m) } else { println("没有实现ICry接口") } }
3 如果结构体A实现了接口P和接口Q,在程序中接口P绑定了A,但A仍然实现了接口Q,即利用类型断言的时候,可直接让接口Q绑定A,
package main import "fmt" type Intfe1 interface { GetName() string } type Intfe2 interface { GetAge() int } type father struct { name string } type son struct { father name string } func (f *father) GetName() string { fmt.Println(f.name) return f.name } func (s *son) GetName() string { fmt.Println(s.name) return s.name } func (s *son) GetAge() int { return 5 } func main() { var i2 Intfe2 s := son{father: father{name:"jack"}, name: "tom"} i2 = &s if s_copy,ok := i2.(Intfe1); ok{ fmt.Println(s_copy) println("实现了接口Intfe1") } }
4 结构体A实现了接口I中的方法M,并且结构体里的很多属性也实现了这方法时,调用该方法就是调用的A实现的方法,这里相当于重写了该方法,这里和结构体的属性特点是一样的,都是就近原则,当结构体的父类和爷类里都有某个属性时,默认调用父类的,
package main import "fmt" type Intfa interface { GetName() } type father struct { name string } type son struct { father name string } func (s son) GetName() { fmt.Println("GetName方法重写了,调用最后重写的方法") fmt.Println(s.name) } func (f father) GetName() { fmt.Println(f.name) } func main() { var i Intfa s := son{father:father{name: "tom"}, name: "jack"} i = s i.GetName() }
参考:https://learnku.com/docs/qianxi-golang/section-4-method-rewriting/6428