Go雖然是面向對象編程,但Go沒有函數的繼承語法,而是支持給任何類型(不包括指針類型)增加新方法的語法,只需要實現該接口要求的所有方法即可。
直接看以下幾個代碼例子
//例:給內置類型 int 添加Less方法
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
func (a *Integer) Add(b Integer) {
*a += b
}
func main(){
var a Integer = 1
if a.Less(21) {
fmt.Println(a, "Less 21")
}
a.Add(2); // a=3
}
//自定義結構體
//順帶複習下結構體的初始化
type Rect struct{
x,y float64
width,height float64
}
func (r *Rect) Area() float64{
return r.width * r.height
}
func main(){
r1 := new(Rect)
r2 := &Rect{}
r3 := &Rect{0,0,1,2}
r4 := Rect{ width:1.1, height:2.3 }
r5 := Rect{ x:1.0, y:2.0, width:1.1, height:2.3 }
r1.Area()
r2.Area()
r3.Area()
r4.Area()
r5.Area()
}
雖然Go語言沒有繼承,但有類似於繼承的做法,稱爲匿名組合;
看代碼:
// 代碼演示 類似繼承 的 匿名組合 語法
type Base struct {
Name string
}
func (base *Base) Foo(){
}
func (base *Base) Bar(){
}
type Foo struct{
Base // 組合
Age int
Addr string
}
func (foo *Foo) Bar(){
foo.Base.Bar() //調用組合結構中的接口
}
func main(){
Foo f
f.Bar()
f.Base.Bar()
//f.Bar() 和 f.Base.Bar() 調用效果完全一致
}
//本例子可以直觀演示 匿名組合 的使用技巧
type Job struct{
Command string
*log.Logger //相當於'繼承'了log.Logger,可以直接使用log.Logger中的方法
}
func (job *Job) Start(){
job.Log("starting now ...")
// todo
job.Log("started")
}
//對於Job結構的使用者來說,根本不用知道log.Logger類型的存在
//匿名組合中出現同名變量或同名組合者的情況
//1.同名變量
type X struct{
Name string
}
type Y struct{
X // X.Name被隱藏,被外層的Name覆蓋
Name string
}
//2.同名組合者
type Logger struct{
Level int
}
type Y struct{
*Logger
Name string
*log.Logger
}// 存在名稱都爲Logger的組合者
//如果沒有使用Logger中的成員,會被忽略衝突,編譯不會報錯;
//否則會存在二義性錯誤;