所以说只实现接口的部分方法 != 实现该接口------那么就不可以将对象赋值给该接口
package main
import "fmt"
type Animal1 interface {
say()
}
type Animal2 interface {
color()
}
type felid interface {
Animal1
Animal2
}
type cat struct {
name string
colorful string
}
func (c *cat) say() {
fmt.Println(c.name)
}
//func (c *cat) color() {
// fmt.Println(c.colorful)
//}
func main() {
var animal Animal1 //
var f felid //对象赋值给接口最好使用new
f = &cat{"ss", "ss"}
fmt.Printf("%T\n", f)
animal = f //对象赋值给接口,实现了该接口的方法
/*相当于f对象赋值给接口,只能调用say()方法*/
animal.say()
/*对象赋值给接口,对象必须实现接口的所有方法*/
var dog Animal2
dog = f
dog.color()
//f = animal //小的往大的扩展报错,不允许
}
*main.cat
ss
1。 可以将一个对象赋值给一个接口,只要这个对象实现了这个接口所定义的方法(这里的方法接收器可以是对象或对象指针),但是通过这个接口只能调用接口内的方法,不能直接使用对象的数据成员的。
- 接收器是指针*T时,接口实例必须是指针(即赋值给接口的是对象的指针)
- 接收器是值 T时,接口实例可以是指针也可以是值(效果是一致的)
再次体验
package main
import (
"fmt"
)
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
//func (a *Integer) Add(b Integer) {
// *a += b
//}
type Lesser interface {
Less(b Integer) bool
}
type LessAdder interface {
Less(b Integer) bool
Add(b Integer)
}
func main() {
fmt.Println("start ...")
var inter Integer = 1
var lesser Lesser = inter //对象赋值给该接口就实现了该方法。
isLess := lesser.Less(3)//
fmt.Println(lesser, "less 3 is ", isLess)
var lessAdder LessAdder = &inter //报错了,必须实现所有方法
lessAdder.Add(3)
fmt.Println("lessAdder add 3 is ", inter)
fmt.Printf("%T",lessAdder)
fmt.Println("lessAdder is ",*lessAdder) //该条语句不能通过编译,接口对象不可以访问对象的元素
}
理解结构体参数为接口的情况下
智能判定根据接口的实现,调用对应的方法
package main
import "fmt"
type IAnimal interface {
Run()
}
func (a *Animal) Run() {//接口的方法。
fmt.Printf("Animal Run.\n")
}
func (a *Animal) Escape(ianimal IAnimal) {//非接口的方法,即特有的方法。
fmt.Printf("对象赋值给接口后,接口变成对象类型,但是只能访问对象特有的方法%T\n",ianimal)
ianimal.Run()
}
type Dog struct {
s Animal//继承了Animal结构体,否则不可以调用对象的函数Escape
//Animal//继承了Animal结构体,否则不可以调用对象的函数Escape
/*匿名字段,可以直接匿名字段的方法*/
//s int//继承了Animal结构体,否则不可以调用对象的函数Escape
}
type Animal struct{}
func (d *Dog) Run() {//接口方法实现才可以让 对象赋值的接口调用该
fmt.Printf("Dog Run.\n")
}
func main() {
dog := &Dog{}
dog.s.Escape(dog) //触发 Dog Run智能判定
//dog.Escape(dog) //触发 Dog Run
/*对象赋值给接口*/
ad:=&Animal{}
ad.Escape(ad)//触发 Animal Run
}
这样就可以理解结构体的元素为接口类型
package main
import "fmt"
type IAnimal interface {
Run()
}
type IncludeInterface struct {
iAnimal IAnimal
}
type empty interface {
test()
}
func Newinstance(a IAnimal)empty {
//因为对象赋值给接口,那么必须声明接口对象!!!!!!!!!!!!!!!!!!!!!!!
//IncludeInterface{a}.test()
//a.test() //报错,必须对结构体赋值后才可以使用对应的方法
a.Run() //可以调用接口自身的方法
return &IncludeInterface{a}//对象赋值给接口empty,必须实现接口的所有方法
}
///////必须要有此方法才行
func (t *IncludeInterface)test() {
fmt.Println("思考,路径上的伤痛,铭记2060")
}
func (a *Animal) Run() { //接口的方法。
fmt.Printf("Animal Run.\n")
}
func (a *Animal) Escape(ianimal IAnimal) { //非接口的方法,即特有的方法。
fmt.Printf("对象赋值给接口后,接口变成对象类型,但是只能访问对象特有的方法%T\n", ianimal)
ianimal.Run()
}
type Dog struct {
s Animal //继承了Animal结构体,否则不可以调用对象的函数Escape
//Animal//继承了Animal结构体,否则不可以调用对象的函数Escape
/*匿名字段,可以直接匿名字段的方法*/
//s int//继承了Animal结构体,否则不可以调用对象的函数Escape
}
type Animal struct{}
func (d *Dog) Run() { //接口方法实现才可以让 对象赋值的接口调用该
fmt.Printf("Dog Run.\n")
}
func main() {
dog := &Dog{}
Newinstance(dog).test()
dog.s.Escape(dog) //触发 Dog Run智能判定
//dog.Escape(dog) //触发 Dog Run
/*对象赋值给接口*/
ad := &Animal{}
ad.Escape(ad) //触发 Animal Run
}