Go 18.0 专业五


什么是方法

<h1>单元目标</h1> <ul> <li>结构体类型调用方法</li> <li>任意类型方法</li> <li>函数与方法的区别</li> </ul> <h2>什么是方法</h2> <p>在Go语言中方法和函数类似,也可以认为方法是特殊类型的函数,只不过方法限制了接收者,方法也可以说是包含了接收者的函数。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/17/172c20329f13590f~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/19/172c83df62f1f01a~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <h2>结构体类型调用方法</h2> <pre><code>package main import ( "fmt" ) func main() { //使用Role结构体创建一个角色代表任我行 rwx := Role{"任我行", "吸星大法", 10, 9.9} rwx.Kungfu()//调用这个结构体的方法。 } //创建一个结构体代表人物角色--任我行 type Role struct { Name string //姓名 Ability string //技能 Level int //级别 Kill float64 //杀伤力 } //创建一个方法,只要是Role结构体就能调用。 func (r Role) Kungfu() { fmt.Printf("我是:%s,我的武功:%s,已经练到%d级了,杀伤力%.1f\n", r.Name, r.Ability, r.Level, r.Kill) }</code></pre> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/19/172c82bdea876f3a~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/18/172c7a932df412c9~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <h2>指针类型方法</h2> <p>方法的接收者可以是结构体类型,也可以是一个值,或者是一个指针类型。</p> <pre><code>package main import ( "fmt" ) func main() { rwx := &amp;Role{"任我行", "吸星大法", 8, 10} rwx.Kungfu() //使用Role该类型的指针调用方法 zwj := &amp;Role{"张无记", "九娘神功", 9, 12} zwj.Kungfu2() //调用指针类型方法 } //创建一个结构体代表人物角色--任我行或者张无忌 type Role struct { Name string //姓名 Ability string //技能 Level int //级别 Kill float64 //杀伤力 } func (r Role) Kungfu() { fmt.Printf("我是:%s,我的武功:%s,已经练到%d级了,杀伤力%.1f\n", r.Name, r.Ability, r.Level, r.Kill) } //指针类型方法 func (r *Role) Kungfu2() { fmt.Printf("我是:%s,我的武功:%s,已经练到%d级了,杀伤力%.1f\n", r.Name, r.Ability, r.Level, r.Kill) }</code></pre> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/18/172c8170ee80042b~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <h2>任意类型方法</h2> <p>在Go语言中,使用<code>type</code>关键字可以定义出新的自定义类型,有了自定义类型之后我们就可以为自定义类型添加各种方法了。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cf3ce265507e4~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <pre><code>package main import ( "fmt" ) // 将好家伙 定义为int类型 type Haojiahuo int // 使用Clear方法将Haojiahuo的所有值清空 func (h Haojiahuo) Clear() bool { h = 0 return h == 0 } // 使用Add方法给Haojiahuo增加值 func (h Haojiahuo) Add(num int) int { return int(h) + num } func main() { var h Haojiahuo fmt.Println(h.Clear()) //调用清空方法 fmt.Println(h.Add(2)) //调用添加方法加2 fmt.Println(h.Clear()) //调用清空方法 fmt.Println(h.Add(6)) //调用添加方法加6 fmt.Println(h.Clear()) //调用清空方法 fmt.Println(h) }</code></pre> <p><code>函数与方法的区别</code></p> <ul> <li>方法限制某个类别的行为,需要指定调用者。函数是一段独立的功能代码,可以直接调用。</li> <li>方法名称可以相同,只要接收者不同就可以,函数命名上不能冲突。</li> </ul> <h2>Go语言实现面向对象</h2> <p>其实在Go语言中是没有面向对象的,但是Go语言的语法设计,我们可以借助结构体,方法,接口的实现,来模拟其他语言中的面向对象的概念。首先了解一下什么是面向对象,面向对象中的三大特征是:</p> <ul> <li><code>封装</code> 在意义上是把许多客观的事物封装成一个抽象的类,把自己的属性 方法只让可信的对象操作。</li> <li><code>继承</code> 子类可以访问父类的属性和方法,子类也可以拥有自己的属性和方法。子类可以重写父类的方法。</li> <li><code>多态</code> 是指一个程序中同名的方法共存的情况,调用者只需使用同一个方法名,系统会根据不同情况,调用相应的不同方法,从而实现不同的功能。多态性又被称为“一个名字,多个方法”。</li> </ul> <h3>1,使用结构体来实现封装</h3> <p>Go语言中没有像java或者.net中的class类,不过可以把struct结构体看成一个类,结构体如果用面向对象的思维来理解,结构体把字段封装到一起,数据被保护在结构体内部,程序需要访问字段的时候,需要通过结构体来访问。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cf6c3c1c7341b~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <pre><code>package main import ( "fmt" ) // 定义结构体实现封装 type Haojiahuo struct { Name string Age int } //使用NewPerson方法创建一个对象 func NewPerson(name string) *Haojiahuo { return &amp;Haojiahuo{ Name: name, } } // 使用SetAge方法设置结构体成员的Age func (h *Haojiahuo) SetAge(age int) { h.Age = age } // 使用GetAge方法获取成员现在的Age func (h *Haojiahuo) GetAge() int { return h.Age } func main() { //创建一个对象 h := NewPerson("好家伙") h.SetAge(18) //访问封装的方法设置年龄 fmt.Println(h.Name, h.GetAge()) //使用对象封装的方法获取年龄 }</code></pre> <h3>2,继承的实现</h3> <p>继承可以解决代码复用的问题,结构体内嵌套一个匿名结构体,也可以嵌套多层结构体。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cfa84486a7dd5~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cfd1681e247ba~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <pre><code>package main import ( "fmt" ) // 创建一个结构体起名 Ouyangcrazy 代表父类 type Ouyangcrazy struct { Name string Age int Ability string } //创建一个结构体代表子类 type YangGuo struct { Ouyangcrazy //包含父类所有属性 Address string //单独子类有的字段 } // 父类的方法 func (o *Ouyangcrazy) ToadKongfu() { fmt.Println(o.Name, "的蛤蟆功!") } //子类的方法 func (y *YangGuo) NewKongfu() { fmt.Println(y.Name, "子类自己的新功夫!") } //子类重写父类的方法 // func (y *YangGuo) ToadKongfu() { // fmt.Println(y.Name, "的新蛤蟆功!") // } func main() { o := &amp;Ouyangcrazy{Name: "欧阳疯", Age: 70} //创建父类 o.ToadKongfu() //父类对象访问父类方法 y := &amp;YangGuo{Ouyangcrazy{Name: "杨过", Age: 18}, "古墓"} //创建子类 fmt.Println(y.Name) //子类对象访问父类中有的字段 fmt.Println(y.Address) //子类访问自己的字段 y.ToadKongfu() //子类对象访问父类方法 y.NewKongfu() //子类访问自己的方法 //y.ToadKongfu() //如果存在自己的方法 访问自己重写的方法 }</code></pre> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cfc64058e4c1c~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p>

页面列表

ITEM_HTML