以下代码是从sort包提取出来的:
package main
import (
"fmt"
)
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
// Array 实现Interface接口
type Array []int
func (arr Array) Len() int {
return len(arr)
}
func (arr Array) Less(i, j int) bool {
return arr[i] < arr[j]
}
func (arr Array) Swap(i, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
// 匿名接口(anonymous interface)
type reverse struct {
Interface
}
// 重写(override)
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
// 构造reverse Interface
func Reverse(data Interface) Interface {
return &reverse{data}
}
func main() {
arr := Array{1, 2, 3}
rarr := Reverse(arr)
fmt.Println(arr.Less(0,1))
fmt.Println(rarr.Less(0,1))
}
运行结果:
第30行匿名接口Interface作为结构体reverse的属性;第39行将接口Interface作为参数传到Reverse方法中,来构造reverse;最后第35行通过调用Interface属性的Less方法来重写Less方法。
我们知道,结构体Array实现了Interface定义的三种方法Len,Less,Swap,所以Array实现了Interface接口。
现在我们把Interface接口作为reverse的属性(第30行),并在初始化reverse结构体时,将Interface类型变量作为形参(第39行),就可以在后面具体实现中灵活地将实现了Interface接口的具体结构体作为属性传给reverse结构体(第45行),即reverse结构体得到了该具体结构体实现的方法。这样要重写方法也可在该具体结构体基础上重写(第35行)。
如果不使用匿名接口,要想实现重写,通过组合匿名结构体实现:
package main
import (
"fmt"
)
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
type Array []int
func (arr Array) Len() int {
return len(arr)
}
func (arr Array) Less(i, j int) bool {
return arr[i] < arr[j]
}
func (arr Array) Swap(i, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
// 匿名struct
type reverse struct {
Array
}
// 重写
func (r reverse) Less(i, j int) bool {
return r.Array.Less(j, i)
}
// 构造reverse Interface
func Reverse(data Array) Interface {
return &reverse{data}
}
func main() {
arr := Array{1, 2, 3}
rarr := Reverse(arr)
fmt.Println(arr.Less(0, 1))
fmt.Println(rarr.Less(0, 1))
}
仔细对比可以发现匿名接口的优点,匿名接口的方式不依赖具体实现,可以对任意实现了该接口的类型进行重写。
实现装饰器模式:
package main
import "fmt"
type Component interface {
Describe() string
GetCount() int
}
type Fruit struct {
Count int
Description string
}
func (f *Fruit) Describe() string {
return f.Description
}
func (f *Fruit) GetCount() int {
return f.Count
}
//装饰结构体
type AppleDecorator struct {
Component //采用匿名组合的方式将接口Component作为结构体的属性
Type string
Num int
}
func (apple *AppleDecorator) Describe() string {
return fmt.Sprintf("%s, %s", apple.Component.Describe(), apple.Type)
}
func (apple *AppleDecorator) GetCount() int {
return apple.Component.GetCount() + apple.Num
}
func CreateAppleDecorator(c Component, t string, n int) Component {
return &AppleDecorator{c,t,n}
}
func main(){
var comp Component = &Fruit{Count: 8, Description: "水果统称"}
//Fruit作为参数传给CreateAppleDecorator
result := CreateAppleDecorator(comp, "apple", 20)
fmt.Println(result.Describe())
fmt.Println(result.GetCount())
}