对于每个语言都有属于自己的访问控制权限 对于Java来说:OC中提供了4个访问控制符: @private @package @protected @public 。 对于iOS开发工程师使用OC语言的来说:OC中提供了4个访问控制符: @private @package @protected @public 。 而对于iOS开发工程师还有一种是使用Swift来🔨代码的,那么对应Swift的访问控制 open, public, internal, fileprivate, private 这五个。
open : module以外可以访问、重写或者继承。 public : module以外可以访问、不能重写或者继承。 internal (默认):当前module可用 fileprivate : 当前file可见 private :当前声明区域可见 当你的module的某些类或者方法不想对外提供继承或者重写的权限时可以使用public,而不必使用final。 一个建议是自定义类默认设置为final而不是默认的final(除非有继承的需求),这样可以提高编译速度。
来看看代码
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = A.init()
a.method()
}
}
class A {
open var opena = 10 //module以外可以访问、重写或者继承。
public var publicb = 10 //module以外可以访问、不能重写或者继承。
internal var internalc = 10 //当前module可用
fileprivate var fileprivated = 10 // 当前file可见
private var privatee = 10 //当前声明区域可见
}
extension A {
func method() {
print(opena)
print(publicb)
print(internalc)
print(fileprivated)
print(privatee)
}
}
都在一个model里面 ,没有问题!! 而这个如果要调用A类里面的成员变量除了用private声明的不可以被调用,其余都有正常被调用。因为private定义为了私有也就只能在A类使用。 而这时候如果我们把extension放在不同文件里就会发生使用fileprivated声明的变量报错了,'xxxxxx' is inaccessible due to 'fileprivate' protection level 就是访问权限问题!!fileprivated也就是文件内私有,也在当前的.switf可用。 那internal、public和opena如何测试?如何在不同module呢? 先回答最后一个问题,如何在不同Module呢?可以使用打包的方式。那如何打包呢?可以参考小编的打包静态库教程 首先搞一个静态库静态库里面有一个Utils文件下面对应的类及代码如下:
open class UtilsAA: NSObject {
open var openA = 10
public var publicB = 199
var c = 1000
}
public class UtilsBB: NSObject{
open var openD = 10
public var publicE = 199
var F = 1000
}
class UtilsCC: NSObject {
open var openG = 10
public var publicH = 199
var i = 1000
}
CC这边不是用任何访问权限,那么对应的就是默认的internal 。在不同的Module下面调用情况如下 代码如下:
override func viewDidLoad() {
super.viewDidLoad()
let a = UtilsAA.init()
print(a.openA)
print(a.publicB)
print(a.c)
let b = UtilsBB.init()
print(b.openD)
print(b.publicE)
print(b.F)
let c = UtilsCC.init()
}
也就是如果不使用访问修饰符或者使用了internal 修饰符,那么可以在整个module都可以访问的到。 而open 和public 在module外都可以访问的到,再来说说这两个最大的区别就是能不能被继承和重写。我们不改变静态库里的代码,在使用静态库的地方分别对他进行继承看看效果: 效果如下:
class UtilsAAAA: UtilsAA {
func sayNumber() {
print(openA)
print(publicB)
}
}
class UtilsBBBB: UtilsBB{
func sayNumber() {
print(openD)
print(publicE)
}
}
Cannot inherit from non-open class ‘UtilsBB’ outside of its defining module中文意思为:无法从其定义模块之外的非开放类“UtilsBB”继承 。也就是因为我们的UtilsBB这个类是用Public修饰的,而使用了Public的类在module外是不能被继承的,只有使用open修饰符才能在module外被继承。 再来看看重写的时候open和public的区别 ,同样的在静态库中增加
open class UtilsDD: NSObject {
open func UtilsDD_sayHello(){
print("say hello")
}
public func UtilsDD_sayHi(){
print("say Hi")
}
}
在调用静态库的时候重写里面的方法
class UtilsDDDD: UtilsDD {
override func UtilsDD_sayHi() {
print("Override !!")
}
override func UtilsDD_sayHello() {
print("Override !!")
}
}
可见,Overriding non-open instance method outside of its defining module 也已经告诉我们了,非open对象修饰的是不能被重写的。
都看到这了还不来一个一键三连?????
|