3 3 接口与多态

3.3 接口与多态 #

今天和大家聊聊 golang 的接口( interface

本节源码位置 https://github.com/golang-minibear2333/golang/blob/master/3.grammar-advancement/3.3-interface

3.3.1 接口 #

接口同 java 一样,可以把一堆有共性的方法定义在里面,但是比 java 灵活的是,不需要显式实现接口,你可以自己控制实现哪些方法。

不需要显式实现的意思是,不需要像 java 那样 implements interface 写出来,别急,看完下面的例子就知道了。

定义一个接口。

type humanInterface interface {
	eat() string
	play() string
}

定义一个结构体(类)

type man struct {
	name string
}

实现接口,语法和 给结构体添加方法 一样,完全看不出来 接口 的身影。

func (p man) eat() string {
	return "eat banana"
}

func (p man) play() string {
	return "play game"
}

上面的代码给结构体添加了和接口一样的方法,只要完全实现接口中的方式,默认这就实现接口(隐式)。

用下面这样的格式,把结构体赋值给接口来实现他 接口实例 = new(类型)

var human humanInterface
human = new(man)
fmt.Println(human.eat())
fmt.Println(human.play())

输出

eat banana
play game

PS: new 关键字和 c++ 中的不同,释放内存由 go 的垃圾处理机来做,不需要自己释放内存。

3.3.2 这不是接口 #

上面的是一个很简单实现接口的例子。 要注意的是,必须实现了所有接口的方法才算是实现了这个接口。

假如我们只实现了接口中的一个方法,会发生什么事?

type dogInterface interface {
	eat() string
	play() string
}

type dog1 struct {
	name string
}

func (d dog1) eat() string {
	return "Eat dog food"
}

var dog dogInterface
dog = new(dog1)

报错

报错:Cannot use 'new(dog1)' (type *dog1) as type dogInterface in assignment
Type does not implement 'dogInterface' as some methods are missing: play() string more...

3.3.3 多态 #

当然,多态是面向对象的灵魂, go 怎么能没有?

这是一个以接口为参数的函数,方法内调用了接口中方法。

func humanDoWhat(p humanInterface) {
	fmt.Println(p.eat())
	fmt.Println(p.play())
}

传入不同的类(结构体)

w := woman{"lisa"}
m := man{"coding3min"}
// 多态的含义就是不需要修改函数,只需要修改外部实现
// 同一个接口有不同的表现
humanDoWhat(w)
humanDoWhat(m)

不同输出

lisaeat rice
lisawatch TV
coding3mineat banana
coding3minplay game

java 中的多态有三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

但是 go 没有继承、重写, go 作为一种优雅的语言, 给我们提供了这种解决方案,那就是鸭子类型:看起来 像鸭子, 那么它就是 鸭子

3.3.4 练习 #

练习题目-practice.go

3.3.5 小结 #

interfacego中是一种神奇的存在,interface{} 可以代表所有类型的基类,interface 也可以定义为类的方法模板,只不过在Go中是隐式的实现。

这是一种很奇妙的体验,以后在工作或实战中很快就会熟悉了。



本图书由小熊©2021 版权所有,所有文章采用知识署名-非商业性使用-禁止演绎 4.0 国际进行许可。