1、实现方法
package main import "fmt" //在面向对象编程中,一个对象其实就是一个简单的值或者一个变量,在这个 //对象中包含一些函数 //这种带有接受者的函数,我们称之为方法,本质上,一个方法 //则是一个和特殊类型关联的函数 //定义一个方法,实现两个数相加 type myint int //传统的定义方式,面向过程的方式定义函数 func Add(a,b myint) myint{ return a + b } //面向对象的方式定义方法,这个意思是AddOOP这个方法是属于a这个类型的。方法和函数的不同就是方法有一个接受者,这里的接受者就是a这个类型 //这里必须要是自定义类型,比如这里就不能使用int,可以是指针类型和非指针类型 //可以为基础类型添加方法,也可以为结构体类型添加方法,下面的例子就是为基础类型添加方法 func (a myint)AddOOP(b myint) myint{ return a + b } //为结构体添加类型 type Person struct { name string age int sex byte } func (p Person )PrintInfo() { fmt.Println(p.name,p.age,p.sex) } func main() { var a myint = 1 var b myint = 1 //调用函数 fmt.Println(Add(a,b)) //2 //调用基础类型的方法 fmt.Println(a.AddOOP(b)) //2 //调用结构体的方法 c := Person{name:"test",age:12,sex:'m'} c.PrintInfo() //test 12 109 }
2、指针类型和非指针类型
package main import "fmt" type Person1 struct { name string age int sex byte } //这种指针类型作为接受者,引用语意 func (p *Person1) PrintPointer() { (*p).name = "test1" p.age = 13 (*p).sex = 'f' } func (p Person1) PrintValue() { p.name = "test2" p.age = 14 p.sex = 'm' } func main() { p1 := Person1{name:"abc",age:12,sex:'a'} fmt.Println("调用方法前--->",p1) //调用方法前---> {abc 12 97} (&p1).PrintPointer() fmt.Println("调用方法后--->",p1) //调用方法后---> {test1 13 102} p2 := Person1{name:"abcd",age:10,sex:'c'} fmt.Println("调用方法前--->",p2) //调用方法前---> {abcd 10 99} p2.PrintValue() fmt.Println("调用方法后--->",p2) //调用方法后---> {abcd 10 99} }
如果指针类型作为方法的接受者,在方法内部修改这个对象,是修改的一份数据,对外部的结构体是有影响的
如果是一个结构体作为方法的接受者,在方法内部修改这个对象,是修改的另外一份数据,对外部的结构体是没有影响的
3、实现继承和重写
package main //go语言的继承 import "fmt" type Person2 struct { name string age int sex byte } func (p *Person2) PrintValue2() { fmt.Printf("%s,%c,%d/n",p.name,p.sex,p.age) } //写一个子类,继承Person父类 type Student31 struct { Person2 id int addr string } //为Student31这个结构体定义方法,如果父类有一个相同的方法,则相当于重写父类的方法 func (p *Student31) PrintValue3() { fmt.Printf("%s,%c,%d/n",p.name,p.sex,p.age) fmt.Printf("%d,%s/n",p.id,p.addr) } func main() { p1 := Person2{name:"abc",age:12,sex:'a'} //父类调用父类的方法 (&p1).PrintValue2() //abc,a,12 p2 := Student31{Person2:Person2{"ddd",12,'f'},id:10,addr:"dddddddddd"} //子类调用父类的方法 (&p2).PrintValue2() //ddd,f,12 //子类调用重写的方法 (&p2).PrintValue3() //ddd,f,12 //10,dddddddddd //如果子类和父类有相同的方法,如果一定要调用父类的方法,则用下面的方式来调用 //p2.Person2.PrintValue2() }
4、调用方法的三种方法
package main import "fmt" type Person3 struct { name string age int sex byte } func (p *Person3)Test1() { //%p表示地址,%v表示值 fmt.Printf("%p,%v",p,p) } func main() { p1 := Person3{name:"abc",age:12,sex:'a'} //传统的调用方法 (&p1).Test1() //0x1f4400d0,&{abc 12 97 //使用go的方法值特性调用方法,也就是说用对象去调用方法 pFunc := p1.Test1 pFunc() //0x1f43e0d0,&{abc 12 97} //使用方法表达式调用方法,用类的的指针去调用 pFunc2 := (*Person3).Test1 pFunc2(&p1) //0x1f43e0d0,&{abc 12 97} }
5、定义setter和getter方法
package main import "fmt" type Dog struct { name string age int sex byte } //封装dog的方法 //setter func (p *Dog)setName(name string) { p.name = name } //getter func (p *Dog)getName() string { return p.name } func (p *Dog)run() { fmt.Printf("runrun%s/n",p.name) } func main() { d1 := Dog{name:"abc",age:12,sex:'a'} d1.setName("dooooo") d1.getName() d1.run() }
面向对象实现方法
package main import "fmt" type P1 struct { oop1 string oop2 string oop3 int } type P1_1 struct { P1 oop4 string oop5 string oop6 byte } //test11_1这个方法属于一个指针变量,而这个指针变量必须指向P1这个结构体 func (p *P1)test11_1(n int) { p.oop3 += n fmt.Println(p) } func (p *P1_1)test11_1(n int) { p.oop3 += n * 2 fmt.Println(p) } //test11_1这个方法属于一个结构体,而这个结构体必须是P1这个结构体的实例 //func (p P1)test11_1(n int) { // p.oop3 += n // fmt.Println(p) //} func main() { test11_2 := &P1{oop1:"oop1",oop2:"oop2",oop3:3} //test11_2 := P1{oop1:"oop1",oop2:"oop2",oop3:3} test11_3 := &P1_1{P1:P1{oop1:"oop1_oop1",oop2:"oop2_oop2",oop3:4},oop4:"oop4_oop4",oop5:"oop5_oop5",oop6:'m'} //test11_3 := P1_1{P1:P1{oop1:"oop1_oop1",oop2:"oop2_oop2",oop3:4},oop4:"oop4_oop4",oop5:"oop5_oop5",oop6:'m'} test11_2.test11_1(2) fmt.Println(test11_2) //如果父类和子类有相同的方法,那么子类去调用这个方法,则默认会调用子类的方法 //test11_3.test11_1(3) //fmt.Println(test11_3) //如果父类和子类有相同的方法,通过下面的方法可以去调用父类的方法 test11_3.P1.test11_1(3) fmt.Println(test11_3) }
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/20925.html