go語言也提供了繼承,但是採用了組合的方式,所以我們將其稱為匿名組合:
package main
import
"fmt"
//定義基類
type base struct
//基類相關的2個成員方法
func (base *base) a()
func (base *base) b()
//定義子類
type son struct
//重寫基類的b方法
func (son *son) b()
func main()}
son.b() //呼叫子類的重寫至基類的b方法
son.a() //呼叫子類繼承至基類的a方法
}
輸出結果:
base method
bcalled...
sonmethod
bcalled...
base
method
acalled...
以上**定義了乙個base類(實現了a()和b()兩個成員方法),然後定義了乙個
son,該類從base類「繼承」並改寫了b()方法(該方法實現時先呼叫了基類的b()方法).
在「派生類」son沒有改寫「基類」base的成員方法時,相應的方法就被「繼承」,例如在
上面的例子中,呼叫son.a()和呼叫son.base.a()效果一致。
與其他語言不同,go語言很清晰地告訴你類的記憶體布局是怎樣的。此外,在go語言中你還
可以隨心所欲地修改記憶體布局,如:
type son struct
這段**從語義上來說,和上面給的例子並無不同,但記憶體布局發生了改變。「基類」 base
的資料放在了「派生類」 son的最後。
另外,在go語言中,你還可以以指標方式從乙個型別「派生」:
type son struct
這段go**仍然有「派生」的效果,只是son建立例項的時候,需要外部提供乙個base類
例項的指標.
如下所示,匿名組合了乙個log.logger指標:
type job struct
在合適的賦值後,我們在job型別的所有成員方法中可以很舒適地借用所有log.logger提
供的方法。比如如下的寫法:
func (job *job)start()
對於job的實現者來說,他甚至根本就不用意識到log.logger型別的存在,這就是匿名組合的
魅力所在.在實際工作中,只有合理利用才能最大發揮這個功能的價值。
我們必須關注一下介面組合中的名字衝突問題,比如如下的組合:
package main
import(
"fmt"
)type x struct
type y struct
func main(),"ychenys"}
fmt.println("y.name = ",y.name) = ychenys
}
組合的型別和被組合的型別都包含乙個name成員,會不會有問題呢?答案是否定的。所有
的y型別的name成員的訪問都只會訪問到最外層的那個name變數,x.name變數相當於被覆蓋了。
Go語言學習 十三 物件導向程式設計 繼承
package main import fmt 定義基類 type base struct 基類相關的2個成員方法 func base base a func base base b 定義子類 type son struct 重寫基類的b方法 func son son b func main son...
十三 物件導向程式設計
1 物件導向基本概念 物件導向的意義在於 類和物件是物件導向中的兩個基本概念 乙個類可以有很多物件,而乙個物件必然屬於某個類 類之間的基本關係 組合 繼承是單向的,子類繼承父類所有的屬性和行為 include struct biology struct animal biology struct p...
go語言學習筆記19 物件導向
package main import fmt type interger int func a interger test b interger interger func main 輸出結果6type integer int 表示的意思是給int型別指定了乙個別名叫integer,別名可以隨便起...