前言
在 Go 语言中,interface中可以定义多种方法,这些方法可以由不同的接收器(即不同的结构体类型)实现。接口是一种定义,它不关心方法的具体实现,只要求实现接口的类型提供了接口声明的所有方法。
每个类型可以实现接口的所有方法,或者只实现接口的一部分方法。如果一个类型实现了接口的所有方法,那么它就完全满足了该接口;如果只实现了部分方法,那么它只部分满足了该接口,但仍然可以被看作是该接口的一个实现。如果希望一个类型实现某个接口的部分方法,而另一个类型实现该接口的剩余方法,可以通过组合(composition)的方式来实现,允许将一个类型的实例作为另一个类型的字段来复用代码和接口的实现。
在 Go 语言中多态性主要是通过接口和组合来实现的。接口定义了一组方法的契约,而组合允许一个类型在内部包含(或组合)另一个类型的值,从而实现代码复用和多态性。以下是通过组合实现多态性的几个关键步骤:
一、组合实现接口
package main
import "fmt"
// 定义一个接口
type Interface interface {
Method1()
Method2()
}
// 第一个类型实现了接口的部分方法
type Type1 struct{}
func (t *Type1) Method1() {
fmt.Println("Method1 is implemented by Type1")
}
// 第二个类型包含了第一个类型,并尝试实现剩余的方法
type Type2 struct {
Type1
}
func (t *Type2) Method2() {
fmt.Println("Method2 is implemented by Type2")
}
func main() {
// 由于 Type2 包含了 Type1,它间接地实现了 Method1
// 同时它自己实现了 Method2,所以 Type2 实现了 MyInterface
var myInterface Interface = &Type2{}
myInterface.Method1() // 输出: Method1 is implemented by Type1
myInterface.Method2() // 输出: Method2 is implemented by Type2
}
第一个类型实现了interface中的部分方法,第二个类型中包含了第一个类型并实现了interface中剩余的方法,因此第二个类型了interface中的全部方法。
二、通过组合实现多态
package main
import (
"fmt"
)
// Animal 接口声明了多种方法
type Animal interface {
Eat() string
Sleep() string
Play() string
}
// Pet 是一个基础类型,实现了 Animal 接口的部分方法
type Pet struct{}
func (p Pet) Eat() string {
return "Eating kibble."
}
func (p Pet) Sleep() string {
return "Sleeping soundly."
}
// Dog 是一个包含 Pet 类型的类型,实现了 Animal 接口的剩余方法
type Dog struct {
Pet
Name string
}
func (d Dog) Play() string {
return d.Name + " is playing fetch."
}
// Cat 是另一个包含 Pet 类型的类型,实现了 Animal 接口的剩余方法
type Cat struct {
Pet
Name string
}
func (c Cat) Play() string {
return c.Name + " is playing with a ball of yarn."
}
在interface中声明了多个方法,在一个基础类型中实现了部分方法, 其它类型包含了这个基础类型并各自实现了interface中剩余的方法,即通过组合方式实现多态功能。