理解对象赋值给接口

所以说只实现接口的部分方法 != 实现该接口------那么就不可以将对象赋值给该接口

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。 可以将一个对象赋值给一个接口,只要这个对象实现了这个接口所定义的方法(这里的方法接收器可以是对象或对象指针),但是通过这个接口只能调用接口内的方法,不能直接使用对象的数据成员的。

  1. 接收器是指针*T时,接口实例必须是指针(即赋值给接口的是对象的指针)
  2. 接收器是值 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
}

猜你喜欢

转载自blog.csdn.net/weixin_42544051/article/details/85257360
今日推荐