Go语言没有关于对象的关键词,没有class,没有extends,没有implements,但是Go语言依然是一种完整的面向对象编程语言,拥有面向对象编程语言的三大特性:封装、继承、多态。

传统的面向对象编程语言通过override和overwrite实现多态,特别是对接口的override,使面向对象编程呈现出迷人的特性:针对接口编程,运行期注入实现,使程序呈现多态的特性。

面向对象设计模式中最让人困惑,最引人入胜的就是那些灵活应用对象多态特性的模式。

而Go语言的多态更加灵活,在传统的面向对象编程中,关于组合还是继承总有许多争论,不良继承又带来诸多问题。

Go语言中组合就是继承(extends),struct中包含另一个struct,就拥有了另一个struct的成员和方法。

//树的中间节点
type node struct{
	*list.List //(匿名)组合即继承,node拥有了list的特性
	name string
}

Go语言定义就是实现(implements),go语言可以定义接口(interface),也可以定义struct上的方法,但是方法不需要显式实现接口,只要方法签名一致就可以,如果一个struct上定义的方法实现了interface上定义的所有方法,那么就认为该struct实现了该接口。

//接口,关于树的遍历操作都在这里
type tree interface{
do()
}

func (l leaf)do(){//定义即实现,leaf实现了tree接口
	fmt.Println(l.name+" leaf do something.")
}

一个完整的关于树的遍历的go语言实现如下,利用go的多态特性,不需要递归。

package main

import(
	"fmt"
	"container/list"
)

//接口,关于树的遍历操作都在这里
type tree interface{
do()
}

//树的中间节点
type node struct{
	*list.List //(匿名)组合即继承,node拥有了list的特性
	name string
}

//树的叶子
type leaf struct{
	name string
}

func (n node)do(){//定义即实现,node实现了tree接口
	for e:=n.Front();e!=nil;e=e.Next(){//node拥有了list的特性
		e.Value.(tree).do()
	}
	fmt.Println(n.name+" node do something.")
}

func (n node)addSub(sub tree){
	n.PushBack(sub)
}

func (l leaf)do(){//定义即实现,leaf实现了tree接口
	fmt.Println(l.name+" leaf do something.")
}

func main() {

	//定义树的节点
	n1 := node{list.New(),"n1"}
	n2 := node{list.New(),"n2"}
	l1 := leaf{"l1"}
	l2 := leaf{"l2"}

	//构造树的结构
	n2.addSub(l2)
	n1.addSub(n2)
	n1.addSub(l1)

	//遍历树
	n1.do()
	
}

以上为树的深度优先遍历,如果想改为广度优先遍历,只需要调整一行代码。

func (n node)do(){//定义即实现,node实现了tree接口
	fmt.Println(n.name+" node do something.")
	for e:=n.Front();e!=nil;e=e.Next(){//node拥有了list的特性
		e.Value.(tree).do()
	}
}