Golang初级系列教程-接口多态性
通过一个具体的实例来说明多态,虽然并不能完全表现多态的性质,但是能够简明概要的讲述多态的特性。假设一个火星人来到地球,只知道地球上有人类,但是却不会区分男人和女人。某一天,在大街上闲逛,向某个人问了问题:“嘿,哥们,你喜欢什么?”。假设当前这个人是个男人,操着一口东北话说:“我喜欢钓鱼”。走着走着,又遇到一个女人,这时火星人又向她问了同样的问题,女人回答到:“我喜欢购物”。一路走一路问,每次都得到不同的回答。哈哈,这个例子烂透了,但是也非常完美的说明了多态的特性——同样类型的实例获得不同的结果。
在 Go
语言中,通过使用 interface
实现这一特性。如果还不知道 interface
,请先阅读Golang初级系列教程-接口。假设我们现在定义了一个 interface
,其它类型实现 interface
定义的方法,这时我们可以通过接口类型去访问这些特定类型的方法而不关心它们具体的类型是什么。让我们通过一个实例形象生动的的展示下我们所说的内容。
package main
import "fmt"
type Human interface {
myStereotype() string
}
type Man struct {
}
func (m Man) myStereotype() string {
return "I'm going fishing."
}
type Woman struct {
}
func (m Woman) myStereotype() string {
return "I'm going shopping."
}
func main() {
m := new (Man)
w := new (Woman)
//an array of Humans - we don’t know whether Man or Woman
hArr := [...]Human{m, w} //array of 2 Humans. One is the type Man, one is the type Woman.
for n, _ := range (hArr) {
fmt.Println("I'm a human, and my stereotype is: ", hArr[n].myStereotype()) //appears as human type, but behavior changes depending on actual instance
}
}
I'm a human, and my stereotype is: I'm going fishing.
I'm a human, and my stereotype is: I'm going shopping.
在上面的代码中,通过 for
循环,可以实现询问同样的问题,但是得到不同的答案。从调用者的角度考虑,只知道这是一个 Human
的实例——但是每次这个 Human
都代表不同的类型,这就是多态喽。
希望上面的例子简单明了。对于我来说,多态是一个复杂的概念,所以我尽量通过简单的例子来描述。如果仔细考虑,上面的代码在实际设计当中,Man
和 Woman
应该是继承自 Human
的。让我们继续扩展上面的代码。
这一次,创建一个接口 Hobby
,而让 Man
和 Woman
继承 Human
。另外,添加 Dog
类,不继承任何类型,但是让其实现 Hobby
接口。通过这样的设计,我们可以通过接口统一调用每种具体类型的 myStereotype()
。
package main
import "fmt"
type Hobby interface {
myStereotype() string
}
type Human struct {
}
func (h Human) myStereotype() string {
return "I'm a Human, only an abstract concept, and I can have no hobby."
}
type Man struct {
Human //anonymous class to inherit Human behavior
}
func (m Man) myStereotype() string {
return "I'm a Man and I'm going fishing."
}
type Woman struct {
Human //anonymous class to inherit Human behavior
}
func (m Woman) myStereotype() string {
return "I'm a Woman and I'm going shopping."
}
type Dog struct {
//does not inherit any other type
}
func (m Dog) myStereotype() string {
return "bow bow bow, I'm chasing sticks."
}
func main() {
h := new (Human)
m := new (Man)
w := new (Woman)
d := new (Dog)
//an array of hobby instances - we don’t need to know whether human or dog
hobbyArr := [...]Hobby{h, m, w, d} //array of 3 Humans and 1 dog.
for n, _ := range (hobbyArr ) {
fmt.Println("My hobby? Well,", hobbyArr [n].myStereotype()) //appears as Hobby type, but behavior changes depending on actual instance
}
}
My hobby? Well, I'm a Human, only an abstract concept, and I can have no hobby.
My hobby? Well, I'm a Man and I'm going fishing.
My hobby? Well, I'm a Woman and I'm going shopping.
My hobby? Well, bow bow bow, I'm chasing sticks.
Golang一种神奇的语言,让我们一起进步