Go与Java(4) Go和Java微观对比-3

150 阅读4分钟

11.Go和Java的访问权限设置区别

首先我们来回忆一下,Java的权限访问修饰符有哪些?

public 全局可见

protected 继承相关的类可见

default 同包可见  

private 私有的,本类可见

关于Java中的访问权限修饰符,是用于修饰变量,方法,类的,被修饰的对象被不同的访问权限修饰符修饰后,其它程序代码要想访问它,必须在规定的访问范围内才可以,比如同包,同类,父子类,全局均可访问。

 

那么,Go中的访问权限设置又有什么区别呢?

 

要理解这个问题,首先我们要来看一下一个Go程序的程序文件组织结构是什么样子的?

 

一个可运行的编译后的Go程序,必须有一个入口,程序从入口开始执行,这个入口必须是main包,并且从main包的main函数开始执行。

 

但是,为了开发的效率和管理开发任务的协调简单化,对于代码质量的可复用,可扩展等特性的要求,我们一般采用面向对象的,文件分模块式的开发。

 

比如,我是一个游戏程序,我的main函数启动后,首先要启动UI界面,那么关于UI界面相关的代码我们一般会专门分出一个模块去开发,然后这个模块有很多个程序文件,这里关于UI模块比如有3个文件,a.go,b.go,c.go,那么我们在实际当中会建一个以ui为名的包文件夹,然后把a.go,b.go,c.go全部放到ui这个包文件夹下,然后因为这个包没有main包,没有main函数,所以它打出来的一个程序文件就是以.a结尾的工具包,类似于Java中的jar包,工具包文件名为 ui.a。

 

参考如下:

 

----com.mashibing.mygame.ui

​ ------------------------------------a.go

​ ------------------------------------b.go

​ ------------------------------------c.go

a.go文件如下示例:

//这里的ui,也就是package后面的名称尽量和包文件夹的名称一致,不一致也可以

package ui


//相关方法和业务

 

func main() {

}

//启动游戏UI

func StartGameUI() {

 

}

这里需要注意一个点,在程序中的 package后面的 ui包名可以和文件夹com.mashibing.mygame.ui中最后一层的ui文件夹名称不一致,

 

我们一般按规范写是要求写一致的,不一致时的区别如下:

 

我们把ui.a打包完毕后,我们就可以在别的程序中用import导入这个包模块 ,然后使用其中的内容了。

 

上面两个ui不同之处在于,在我们import 的代码后面,需要写的模块名称是在 ${gopath}/src/下的文件夹名,也就是com.mashibing.mygame.ui中的ui。

 

例如:

//游戏主程序

package main

 

//这里的ui是com.mashibing.mygame.ui的最后一层文件夹名

import "ui"

 

//相关方法和业务

 

func main() {

//这里的ui不是文件夹名,而是之前a.go程序中package后面写的包名

ui.StartGameUI()

}

接下来进入主题,我们的go语言关于访问修饰符的是指的限制什么权限,以及如何实现?

 

我们之前可以看出来,实战中的go程序是有一个main程序import很多其它包模块,每个模块实现对应的功能,最后统一在main程序中组合来完成整个软件程序,那么有一些其它模块的函数和变量,我只想在本程序文件中调用,不想被其它程序import能调用到,如何实现?

  import后是否能调用对应包中的对象(变量,结构体,函数之类的)就是go关于访问权限的定义,import后,可以访问,说明是开启了访问权限,不可以访问,是说明关闭了其它程序访问的权限。

在go中,为了遵循实现简洁,快速的原则,用默认的规范来规定访问权限设置。

默认规范是:某种类型(包括变量,结构体,函数,类型等)的名称定义首字母大写就是在其它包可以访问,首字母非大写,就是只能在自己的程序中访问。

这样我们就能理解为什么导入fmt包后,他的PrintF函数的首字母P是大写的。  

参照如下代码:


package ui

 

import "fmt"

 

func main() {

//这里的P是大写

//所有调用别的包下的函数,都是首字母大写

fmt.Printf("aa")

}

//这里的Person的首字母P也是表示外部程序导入该包后可以使用此Person类

type Person struct{

 

}

//这里的D同上

var Data string = "li_ming"