標籤:面向 作用 報錯 var 物件導向編程 ring quick person string
主要講的是“類”和介面&和其他傳統語言不一樣的地方挺多的,斷斷續續看了好幾天
下面是我的練習代碼
// GoStudy0219 project main.go/*go語言學習——物件導向編程(1)go中類型的值語義和引用語義結構體(類)的定義和初始化*/package mainimport ("fmt")func main() {//幾種“類”的初始化v1 := &character{"Tom", 100, 10, 100} //這樣定義出來的v1實際上時“類”的地址v2 := new(character) //等價於v4:=&character{}v2.name = "Judy"v2.hp = 50v2.magic = 150v2.attack = 30v3 := &character{name: "Jim", hp: 150} //注意是花括弧v3.magic = 30v3.attack = 20fmt.Println(v1)fmt.Println(v2)fmt.Println(v3)fmt.Println("*********************")//使用類的函數v1.addHp(600)fmt.Println(v1)fmt.Println(v1.hpIsLessThan(*v2))fmt.Println(v2)fmt.Println("*********************")//其他類型var v5 Age = 100fmt.Println(v5)v5.add(10)fmt.Println(v5)v5.errorAdd(10)fmt.Println(v5)fmt.Println("*********************")//值語義和引用語義//基礎資料型別 (Elementary Data Type)int,float之類的時值語義//數組和切片是值語義//map,channel和interface是引用語義}type Age intfunc (this *Age) add(target Age) {*this += target}func (this Age) errorAdd(target Age) {this += target}//結構體(與其他語言中的類地位相同)type character struct {name stringhp float32attack float32magic float32}func (this character) hpIsLessThan(target character) bool { //this character 不會改變thistarget.attack = 66return this.hp < target.hp}func (this *character) addHp(value float32) { //this *character 會改變thisthis.hp += value}
// GoStudy0223 project main.go/*go語言學習——物件導向編程(2)匿名組合可訪問性*/package mainimport ("fmt")func main() {fmt.Println("Hello World!")var stu *student = &student{1001, *&person{"Tom", 10, true}}fmt.Println(stu)stu.greet() //匿名組合,能直接調用匿名的函數的方法fmt.Println(stu.name) //匿名組合能夠直接調用匿名函數的屬性stu.walk() //多態重載的實現var tea *teacher = &teacher{55, "Judy", *&person{"Tom", 10, false}}fmt.Println(tea.name)}type person struct {name stringage intisMan bool}func (this *person) greet() {fmt.Println("hello")}func (this *person) walk() {fmt.Println("walk slow")}type student struct {studentId intperson //匿名組合}func (this *student) walk() { //相當於多態重載,外部調用walk時不再執行匿名函數中的walk函數this.person.walk() //根據需求,實現了“基類”的函數,fmt.Println("walk quick")}type teacher struct {teacherId intname string //person 裡面的name相當於被隱藏了,外部調用teacher.name的時候,person裡面的name並不會起作用person}/*匿名組合相當於用類型名稱(去掉包名部分)作為成員變數的名字,因此,一個類型中如果同時有類似於person和xxx.person的時候可能會報錯,因此要避免這種情況*//*首字母大寫表示包外可訪問,首字母小寫,表示包外不能訪問。同一包內,不論首字母是大寫還是小寫都是能訪問的*/
// GoStudy0224 project main.go/*go語言學習——物件導向編程(3)介面*/package mainimport ("fmt")func main() {fmt.Println("Hello World!")var per = &Person{"Tom", 50}fmt.Println(per)//介面的賦值//用對象賦值var v1 IAdd = per //這裡傳入的實際上是類型的地址v1.Add(10)fmt.Println(per)//用介面賦值var v2 IPerson = pervar v3 IWalk = v2 //函數“全”的介面可以像函數“少”的介面賦值;如果幾個介面中函數相同,則這幾個介面可以相互轉換v3.Walk()if v4, ok := v2.(IRead); ok { //檢測,介面v2能不能轉換成IRead介面v4.Read()}if v5, ok := v2.(*Person); ok { //檢測,介面v2指向的物件類型是不是Personfmt.Println(v5)}var v6 interface{} = per //interface{}是any類型,空介面switch v7 := v6.(type) { //檢測介面指向對象的類型case int:fmt.Println(v7, "int")default:fmt.Println(v7, "other")}var v8 IPerson2 = perv8.Read()}type Person struct {name stringage int}func (this *Person) Add(value int) {this.age += value}func (this *Person) Walk() {fmt.Println("walk")}func (this *Person) Speak() {fmt.Println("speak")}func (this *Person) Read() {fmt.Println("read")}//定義介面type IWalk interface {Walk() //定義介面函數,省略func關鍵字}type IRead interface {Read()}type ISpeak interface {Speak()}type IAdd interface {Add(value int)}type IPerson interface {Walk()Read()Speak()}type IPerson2 interface { //介面的組合,等同於上一個介面的寫法ISpeakIReadIWalk}/*傳統語言的介面是一種契約,使用介面的類必須實現介面的所有方法,不同命名空間下的同名介面也被視為兩個不同的介面eg. C# java等需要考慮定義什麼介面,在哪個類裡面實現介面go語言中,並不需要考慮上面的問題*/
go語言學習(五)——物件導向編程