zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",p.name,p.sex,p.age)
    	fmt.Printf("%d,%s
    ",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
    ",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)
    }
    
  • 相关阅读:
    memcached stats 命令
    sql server 游标语法
    iis 备份
    在Win7下使用超级任务栏时,将文件夹锁定在超级任务栏打开的默认都是计算机
    微点破解90天
    win7 设置 开始菜单 程序 为经典模式
    设置 ASP.NET 存储当前应用程序的临时文件(生成的源、编译了的程序集等)的目录的物理路径。
    Java六大必须理解的问题
    Windows不能在本地计算机启动OracleDBConsoleorcl
    更改phpMyAdmin的密码
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/10878855.html
Copyright © 2011-2022 走看看