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 並不是我頭腦裡所想的東西.計算機裡面只有資料和演算法,資料用於對現實世界抽象建模,演算法對資料演算,這已經很好,怎麼出來乙個物件導向這個 怪胎 物件導向教學每次都要從對現實世界的模擬講起,還記得那個會叫的鴨子...