[原创文章欢迎转载,但请保留作者信息]
Justin 于 2009-12-20
大师写到这一章节的时候文风似有明显转变,原因未知,但我更喜欢这章的风格。如题,Item22的主旨是应该把所有类的数据成员声明为私有(private)。因为:
-
如果数据成员都是私有的,那么访问这些成员就只能通过函数进行。于是用户就不需要费心考虑到底要用什么方式去访问数据成员:因为只有定义了的函数可以用。
-
通过定义数据成员为私有,可以实现函数来设计、约束或禁止对这些成员的各种访问(读/写等)。而如果将其设为公有(public),你将无法得知你的成员会被谁改动,也不知道会是怎样的改动。
-
而更重要的好处是封装(encapsulation):可以方便的通过修改函数来改变成员的访问方式;在成员被访问时通知其他对象;实现多线程中的同步等等。
封装的好处究其本质,是通过对用户隐藏数据成员来保证类行为的一致性(class invariant)。因为接口被成员访问函数限制了,类的作者也为自己日后修改类的实现留了后路:如果所有的成员都是公有的,对任何代码的修改都有可能影响到外界的使用。(因此Scott说“Public means unencapsulated, and practically speaking, unencapsulated means unchangeable, especially for classes that are widely used.”)
那么可不可以声明为保护(protected)呢?其实道理和前面的公有是一样的。公有的成员对类的外部完全开放,而保护的成员对类的继承者完全开放。这个就像两个区间:(-infinity, +infinity) 和 (0, +infinity),两者的大小是一样的。
接下来大师的一句话有击中要害:从分装的角度,只有两种访问级别:私有,及其他。