一看就懂系列之Golang的方法

转载请附上本文地址: https://blog.youkuaiyun.com/u011957758/article/details/81125101

前言

在Go里头是没有类的概念的,但是Go一样实现了同样的效果。
本文主要通过Go和PHP的对比来做笔记,致力于"一篇讲清楚go方法",对于说phper的同学,看完印象会更深刻。

即将get到以下知识小点:
1.Go的方法 vs PHP的类
2.Go的继承 vs PHP的继承
3.重载?重写?
4.指针接收者的方法
5.封装&访问权限说明

正文

1.Go的方法 vs PHP的类

几乎所有广泛应用的语言都支持面向对象编程的思想。当然go也不例外。
在php中的class类的概念,对应到go里头就是方法的概念。

几个重点概念明确下:
1.方法其实是接收者(或者说receiver)上的一个函数。特殊类型的函数罢了
2.接受者必须是内置类型或者结构体的一个或者指针

在php中:

	class person {
		public function PrintName($name) {
			print_r($name);
		}
	}

	$person = new person();
	$person->PrintName('咖啡色的羊驼');

在go中:

	package main

	import (
		"fmt"
	)
	// 定义一个结构体,当作方法接收者
	type Person struct {}      
	
	// 方法声明其实就是在函数的基础上在func后面多增加定义接收者
	// func (r ReceiverType) funcName(parameters) (results)
	func (p Person) PrintName(name string) {
		fmt.Println(name)
	}
	
	func main() {
		cbs := Person {}            // 字面量的方式定义一个person类型
		cbs.PrintName("咖啡色的羊驼") // 直接调用方法
	}
	

是不是感觉很巧妙?go的方式实现了和php类一样的效果,底下可以跟一大丢函数。

2.Go的继承 vs PHP的继承

面向对象的思想里头有个概念叫做继承。

php例子就不写了,直接上go,show your code:

	package main

	import (
		"fmt"
	)
	
	type Person struct {
	}
	
	type SuperMan struct {
		Person      // 通过结构体内嵌包含的方式,来实现继承一样的效果
		Age int 
	}
	
	func (p Person) PrintName(name string) {
		fmt.Println(name)
	}
	
	func (s SuperMan) PrintAge() {
		fmt.Println(s.Age)
	}
	
	func main() {
		cbs := SuperMan{Age:18}
		cbs.PrintName("咖啡色的羊驼")       // 输出"咖啡色的羊驼"
		cbs.Person.PrintName("咖啡色的羊驼")// 输出"咖啡色的羊驼"
		cbs.PrintAge()                    // 输出18
	}
	
	


3.重载?重写?

重载简单的说就是重新定义一个函数名相同,参数个数或者类型不同的函数,并且存在于一个类中(go可以对应与同一个接受者中)。

!!!是的,go里头没有重载!!!

重写就是重新定义一个函数名相同,参数个数和类型也相同的函数,并且存在于同一个类或者子类中(翻译到go就是同一个接受者,或者继承的接受者)。

是的,重写go有了,

但是在go中不是真正严格意义上的面向对象,只是实现方式可以类比,所以go的重写也只是类比,参数不一定要相同,因为实际上还是看调用者调的方法所属的receiver。
~上代码:

	package main

	import (
		"fmt"
	)
	
	type Person struct {
	}
	
	type SuperMan struct {
		Person      // 通过结构体内嵌包含的方式,来实现继承一样的效果
		Age int 
	}
	
	func (p Person) PrintName(name string) {
		fmt.Println(name)
	}
	
	func (s SuperMan) PrintName(name string) {
		fmt.Println(name)
		fmt.Println(1) // 多来一个1以示区别
	}
	
	func (s SuperMan) PrintAge() {
		fmt.Println(s.Age)
	}
	
	func (s SuperMan) PrintName(name string) {
		fmt.Println(name,123)
	}
	
	func main() {
		cbs := SuperMan{Age:18}
		cbs := SuperMan{Age:12}
		cbs.Person.PrintName("咖啡色的羊驼1")// 输出"咖啡色的羊驼"
		cbs.PrintName("咖啡色的羊驼2")       // 输出"咖啡色的羊驼"和1
	}

4.指针接收者的方法

	type Person struct {
		Age float64
	}
	
	// 指针接收者
	func (p *Person) AgeIncr(num float64) {
		p.Age *= num
	}

	func main() {
		cbs := &Person{Age:18}
		cbs.AgeIncr(2)
		fmt.Println(*cbs)   // 输出 '{36}',说明初始化的值被改变了
	}
	

5.封装&访问权限说明

!!划重点!!

1.go语言只有一种控制命令可见性(public or private)的方式:定义的时候,首字母大写就是可以从包中导出(public),反之亦然。

2.go语言中封装的单元是,而不是类型。无论在函数内的代码,还是方法内,或者结构体内的字段对于同一个包中的所有代码都是可见的。

第一点很好理解,来一个例子,来证明一下第二点,:

	type Person struct {
		age float64
	}
	
	func (s Person) PrintAge() {
		fmt.Println(s.age)
	}
	
	func main() {
		cbs := Person{age:18}
		cbs.PrintAge()      
		// 输出18
		// 说明"方法当中可以访问结构当中的私有字段"
		// go语言中封装的单元是包,而不是类型
	}

如果你觉得有收获~可以关注我的公众号【咖啡色的羊驼】~第一时间收到我的分享和知识梳理~
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值