go语言面向对象之方法详解编程语言

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

(0)
上一篇 2021年7月19日 23:53
下一篇 2021年7月19日 23:53

相关推荐

发表回复

登录后才能评论