Go語言學習筆記08 物件導向的類和方法

2021-09-02 02:08:29 字數 3954 閱讀 2938

1.物件導向

go語言從語言型別上來講是乙個非常特殊的語言,程式語言從型別上來劃分可以分成兩大型別。

【面向過程思想性質的程式語言】和【物件導向思想性質的程式語言】

這其中c語言就是經典的面向過程,而c++則是物件導向的絕對經典。

那麼回過來說go語言,其特殊之處在於:

·go語言身為c的衍生語言卻是乙個物件導向語言

·go語言身為物件導向語言卻又不存在類class的概念。

眾所周知,物件導向的語言中各【類】和【物件】的概念是不可能缺少的,

那麼go語言是如何處理在【不存在類和物件】前提下實現物件導向的呢?

原因就是:

·go語言使用了struct結構體來模擬類

·go語言通過struct結構體變數來模擬類的物件

並且·go語言還通過【匿名字段】的手段來模擬了【繼承inheritance】這一物件導向語言的特性。

(1)匿名字段

匿名字段,事實上就是結構體的巢狀。go語言中正是使用匿名欄位來模擬了繼承這一特性。

通過在乙個結構體中宣告另乙個結構體名稱的方式,來賦予結構體額外的屬性

eg:type 結構體名 struct

eg:type father struct

type son struct

func main() , 100}

}(2)同名字段

同名字段,事實上就是父類和子類具有的同名的屬性。

此時直接通過子類訪問該屬性採用就近原則,如果想要通過子類物件訪問父類的同名屬性

則需要通過.點運算,先訪問子類物件中的父類屬性才可以。

eg:子類物件.父類.父類同名屬性

eg:type father struct

type son struct

func main() , 男}

}(3)匿名指標字段

結構體的匿名指標字段,在使用之前需要先new為其分配記憶體空間,因為指標預設是nil。

這與匿名字段不同,匿名字段預設是{}空值,所以可以直接拿來使用。

eg:type father struct

type son struct

func main()

fmt.println(*xiaoming.father);    //

}(4)多重繼承

go語言衍生自傳統c與c++,這一點給go語言帶來了無與倫比的優勢。

最讓人欣慰的一點就是go語言中支援了多重繼承的這一特性。

eg:type 結構體名 struct        

正如前面匿名欄位中所提到的那樣,go語言儘管並不是真正意義上的擁有「繼承」的概念

但是通過某些手段可以模擬出繼承與多重繼承的表現形式。

而上面的寫法,便是多重繼承在go語言中的表現。

eg:type father1 struct

type father2 struct

type son struct

func main() 男的}

}2.(類的)方法

(1)(類的)方法的定義和使用

在很多傳統語言中,對已經封裝好的類進行內容的擴充時一件非常麻煩的事情。

例如在objective-c中對於類的擴充套件就需要依託於category類別來實現。

類別的宣告有擁有其單獨的語法結構,這不得不說是一件非常讓人頭痛的事情。

但是在go語言中對於類的方法擴充套件是一件非常容易的事情,

還是那句話,畢竟在go語言中並不存在真正意義上的類class,都是結構體struct模擬而來

所以對於struct結構體的方法擴充套件就變得簡單起來。

eg:func (形參名 要被擴充套件方法的類名) 擴充套件方法名(擴充套件方法引數列表)擴充套件方法返回值列表

eg://son類

type son struct

//擴充套件給son類的方法sonexfunc

func (tempson son) sonexfunc()

func main() ;

xiaoming.sonexfunc();

}//輸出結果:

// 100

// 男的

ps:其實類的擴充套件是一把雙刃劍,好處是允許我們更靈活的對類進行符合心意的擴充。

但壞處也顯而易見,那就是對於很多系統類來說,我們並不知道其中具體究竟有哪些方法。

對系統類的隨意擴充很容易導致系統類崩潰失效。

因此在go語言中做出了這樣一條對於類的方法擴充套件的限制,那就是:

禁止使用者對於系統類進行擴充,但是在type定義後允許

eg:type int int

func (num int) showself()

func main()

乍一看這似乎和對int系統型別擴充套件並無區別?但是別忘了type是別名定義

當type int int生效的時候,其實已經相當於自定義了乙個具有系統int類所有屬性的自定義類。

而對自定義類int的隨意擴充時不會對系統類int造成任何影響的。

(2)(類的)方法的【值傳遞】與【位址傳遞】

注意值傳遞內部修改無法影響外部,位址傳遞內部可以修改外部就完事。

eg:type son struct

//對son型別物件的方法擴充套件

func (tempson son) sonexfunc(changemoney int, changegender string)

//對son型別物件的指標的方法擴充套件

func (tempson *son) sonpointerexfunc(changemoney int, changegender string)

func main() ;

//值傳遞

xiaoming.sonexfunc(100,"爺們兒");

fmt.println(xiaoming);//                

//位址傳遞

//實際上是(&xiaoming).sonpointerexfunc(1000,"爺們兒");這種寫法

//不過可以簡化成下面的寫法,

//即結構體變數可以直接呼叫結構體指標上的方法

xiaoming.sonpointerexfunc(1000,"爺們兒");

fmt.println(xiaoming);//

}(3)(類的)方法練習

eg:type stuinfo struct

func (tempstu stuinfo) hello()

func main() ;

xiaoming.hello();

}(4)(類的)方法的繼承

方法的繼承實際上就是類的繼承,因為子類在繼承父類的時候不但能繼承父類的成員屬性

還能夠繼承新增在父類上的方法。

eg:type son struct

type grandson struct

func (tempson *son) sonexfunc(changemoney int, changegender string)

func main() }

}(5)(類的)方法的重寫

類的方法既然可以繼承,那麼就存在一種可能:

子類在擁有某個方法的前提下,又繼承來了相同名稱的父類方法。

那麼這事,當使用子類物件去呼叫這個方法的時候,

呼叫的是子類本身的方法還是從父類繼承來的方法?

事實上在很多物件導向的語言中,對方法的重寫都有乙個明確的規定,

那就是【就近原則】

即:如果父類和子類存在同名方法,那麼子類在呼叫時就呼叫子類自己的方法

eg:type father struct

type son struct

func (fa father) showname()

func (so son) showname()

func main() ,"小明"};

xiaoming.showname();//小明

go語言學習筆記19 物件導向

package main import fmt type interger int func a interger test b interger interger func main 輸出結果6type integer int 表示的意思是給int型別指定了乙個別名叫integer,別名可以隨便起...

go語言學習筆記20 物件導向

package main import fmt type human inte ce type student struct func s student sayhi type teacher struct func t teacher sayhi func main i s i.sayhi var...

go語言學習與物件導向再思考

據說smalltalk發明者alan kay就曾經說過 我發明了物件導向,而我可以告訴你c 並不是我頭腦裡所想的東西.計算機裡面只有資料和演算法,資料用於對現實世界抽象建模,演算法對資料演算,這已經很好,怎麼出來乙個物件導向這個 怪胎 物件導向教學每次都要從對現實世界的模擬講起,還記得那個會叫的鴨子...