首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》1.14 隐私

关灯直达底部

我之前曾说过,命名空间本身并非访问内部名字的不可逾越的屏障。不过如果你愿意,它还是可以作为屏障的。比如,并非存储在实例中的所有数据都需要修改,甚至要对其他实例可见。并非每一个实例方法都可以被其他实例调用。任何优秀的基于对象的编程语言都需要通过一种方式确保其对象成员的隐私性——如果不希望其他对象看到这些成员,那么可以通过这种方式做到这一点。

比如:


class Dog {    var name = ""    var whatADogSays = "woof"    func bark {        print(self.whatADogSays)    }    func speak {        print(self.whatADogSays)    }}  

对于上述代码来说,其他对象可以修改属性whatADogSays。由于该属性由bark与speak使用,因此最后可能出现的结果就是,我们让一只Dog吼叫,但它却发出“猫叫声”。这显然不是我们想要的:


let dog1 = Dogdog1.whatADogSays = "meow"dog1.bark // meow  

你可能会说:真够笨的了,为何要使用var声明whatADogSays呢?使用let声明不就行了,让它成为常量。现在就没人能够修改它了:


class Dog {    var name = ""    let whatADogSays = "woof"    func bark {        print(self.whatADogSays)    }    func speak {        print(self.whatADogSays)    }}  

这个答案还不错,但并不是最好的答案。它有两个问题。假设我希望Dog实例本身能够修改self.whatADogSays,那么whatADogSays就必须得是var了;否则,即便实例本身也无法修改它。此外,假设我不希望其他对象知道这只Dog吼的是什么,除非调用bark或是speak才可以。即便使用let声明,其他对象依然还是可以读取到whatADogSays的值。我可不想这样。

为了解决这个问题,Swift提供了关键字private。稍后将会介绍这个关键字的全部含义,不过现在只要知道它可以解决问题就行了:


class Dog {    var name = ""    private var whatADogSays = "woof"    func bark {        print(self.whatADogSays)    }    func speak {        print(self.whatADogSays)    }}  

现在,name是个公有属性,但whatADogSays却是个私有属性:其他对象是看不到它的。一个Dog实例可以使用self.whatADogSays,但引用Dog实例的不同对象(如dog1)就无法使用dog1.whatADogSays。

这里要说明的重要的一点是,对象成员默认是公有的,如果需要访问隐私信息,那就需要请求。类声明定义了一个命名空间;该命名空间要求其他对象通过额外的点符号来引用命名空间内部的事物,不过其他对象依然可以引用命名空间内部的事物;命名空间本身并不会对可见性形成屏障,而private关键字则形成了这道屏障。