golang中不存在private、protected、public,其符号的可见性是在定义符号时设置符号大小写开头来区分。
- 大写:包外可见
- 小写:包内可见
通过这个特性,可以对应的实现Java OOP中封装的概念。
如下
//在该例子中,成员log为小写,包内可见。则如果在同一个包中(如下test方法中),则可以通过name.log的方式访问到golog.Logger中的方法
// demo/bean/name.go
package bean
type Name struct {
log golog.Logger
}
func (n Name)NPrint(){
n.log.Print()
}
func test(){
name:=Name{}
name.log.Print()
}
//但是再其他包中,则只能访问到上面定义的NPrint(),访问不到log成员,也就访问不到golog.Logger中的方法
// demo/file/impl.go
func test(){
name:=bean.Name{}
name.NPrint()
}
//这样也就达到了Java OOP中封装的目的。
如果是匿名组合的话,则类似于继承的概念。
//若为匿名组合,则直接可以访问。而不需通过name.log的方式。
// demo/bean/name.go
type Name struct {
golog.Logger
}
func (n Name)NPrint(){
n.Print()
}
//但是再其他包中,也可以直接访问,并不会隐藏。
// demo/file/impl.go
func test(){
name:=util.Name{}
name.Print() //golog.Logger的方法
}
这是为什么匿名成员是包外可见的呢?
这是因为匿名组合类型是相当于用其类型名称(去掉包名部分)作为成员变量的名字的。
比如上面例子可以写成:
// demo/bean/name.go
type Name struct {
golog.Logger
}
func (n Name)NPrint(){
//下面两种方式都可以
n.Print()
n.Logger.Print()
}
func (n Name)Print(){
n.Logger.Print()
//n.Print() --->注意:如果写成这样就变成无限循环调用自己的Print,而不是Logger的。
}