Go语言-方法

方法

方法是与对象实例绑定的特殊函数。方法是面向对象。方法和函数区别在于前者有前置实例接收参数,编译器以此确定方法所属类型。
可以为当前包,以及除接口和指针以外的任何类型定义方法。

package main
import(
    "fmt"
)
type N int
func (n N)toString()string{        //方法
    return fmt.Sprintf("%#x",n)
}
func main(){
    var a N = 25
    fmt.Println(a.toString())
}

输出:
0x19
方法不支持重载,参数名没有限制。如方法内部并不引用实例,可省略参数名,仅保留类型。

type N int
fun (N)test(){}

方法可以看做特殊的函数,那么前置接受参数的类型自然可以为基础类型或指针类型。可使用实例值或指针调用方法编译器会根据方法receiver类型自动在基础类型和指针类型间转换,但不能使用多级指针的调用方法。
如何选择合适的前置参数类型呢?
- 要修改实例状态,用*T
- 无需修改状态的小对象或固定值建议用T
- 大对象建议用*T,以减少复制成本
- 引用类型、字符串、函数等指针包装对象直接用T
- 若包含Mutex等同步字段,用*T避免因复制造成锁操作无效
- 其他无法确定情况都用*T

匿名字段

可以像访问匿名字段成员那样调用其方法,由编译器负责查找。方法也会有同名覆盖的问题,我们可以利用这种特性实习类似覆盖的操作。

package main
import(
    "fmt"
)
type user struct{}

type manager struct{
    user
}
func (user)toString()string{
    return "user"
}
func (m manager)toString()string{
    return m.user.toString() +";manager"
}
func main(){
    var m manager
    fmt.Println(m.toString())
    fmt.Println(m.user.toString())
}

输出:
user;manager
user

方法集

类型有一个与之相关的方法集,这决定了它是否实现某个接口
- 类型T方法集包含所有receiver T方法
- 类型*T方法集包含所有receiver T + *T方法
- 匿名嵌入S,T方法集包含所有receiver S方法
- 匿名嵌入*S,T方法集包含所有receiver S + *S方法
- 匿名嵌入S或*S,*T方法集包含所有receiver S + *S方法
方法集仅影响接口实现和方法表达式转换,与通过实例或实例指针调用方法无关,实例并不使用方法集,而是直接调用。
面向对象的三大特征“封装”、“继承”、“多态”,Go仅实现部分特性。Go语言中实现继承的方式叫做组合,在上例中有所体现。组合没有父子依赖,不会破坏封装。

发布了27 篇原创文章 · 获赞 7 · 访问量 5万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览