[Basic]面向对象之信息隐藏(三)

来源:互联网 发布:陀螺效应 知乎 编辑:程序博客网 时间:2024/05/16 14:12

Java提供的访问控制与信息隐藏支持

"What's the differences among those access specifiers in Java?" Ashock Dash曾在大三下学期Testing这门课程上提出这个问题。当时作者也凭着答了这个问题,得到一个巧克力,星巴克的,Hmm...味道还不错。

在Java中,与C++类似,也提供了public,protected,private这三个访问符,这三个访问符的意义与C++一样,这里不再赘述了。而与C++不同的是,Java还提供了一个package access,而与public等三种访问权限不同,package access没有关键字。如下面代码所示:

public class Practice {int i = 0; // package access}
那么package access到底意味着什么呢?让我们再看下面的例子:

package com.blue.ex;public class Practice {int i = 0; // package access}
在这里,我们可以看见i变量属于com.blue.ex这个包,那么这时候,我们在这个包再新建一个新的Java文件,包含一个public class。

package com.blue.ex;public class Auxiliary {public static void main(String[] args) {System.out.println(new Practice().i); //OK!}}
这证明,在同一个包里面,我们在另外一个class可以访问到变量i。那么,如果在另外一个包呢?是否还能访问到变量i呢?

package com.blue.plus;import com.blue.ex.Practice;public class Access {public static void main(String[] args) {System.out.println(new Practice().i); //Error!}}
Hoho...很遗憾,即使import了变量i所在的包,还是无法访问到变量i!

于是,Java中的package access意味着:被package access(无关键字)修饰的变量或者方法(读者可以去验证一下方法,比如在Practice类加上一个void print(),去打印i变量),在同一个包里面可以进行访问!

Hmm...我想关于Java的访问控制就讲完了。是的,就这么简单,当理解了C++的访问控制后,Java的访问控制理解起来就是这么的轻松!那么,让我们加点“刺激”性的东西吧。

那么,就来来谈谈Java与C++不同的package。Java为什么会有package这个东西?引入这个东西到底有何用?

当我们在进行系统开发时,我们经常会有一个一个的功能模块。然则,这些功能模块却不一定只有1个程序文件。那么我们这时候为了组织好代码结构,常常需要将这些程序文件放在一个目录下。OK!那么我想我们为这些相似的“一坨”文件取一个形象的名字。让我们想象我们收拾行李时,我们经常把类似的、可以放在一起的东西都放在一个一个包里面,比如生活用品一个包,办公用品一个包。那么,在程序开发中,这些在一起类似的文件为何不就叫package包呢?而在这个例子当中,更阐释了package与C++中的namespace的本质区别。package引入的缘由就在于模块化(module),层次化(hierarchy),然则C++的namespace却不是,C++的namespace引入的缘由却是为了避免函数、变量等名字的穷尽化,用于区分化!

namespace a {int varI = 10;}namespace b {int varI = 20;}int main(int argc,char* argv[]) {std::cout << a :: varI << std::endl; // 10std::cout << b :: varI << std::endl; // 20return 0;} 
如上面的例子,即使都为变量名都为varI,也能通过特定的namespace进行访问控制以及区分。那么,Java中的package可以做到这点吗?我想我不会告诉你,package也是可以完成这项功能的,只是Java的package的重点在于模块化,层次化。我想你很少见到在C++中,会有一个namespace是a::b::c::....等几个层次的,然则在Java中,几个层次却是常事,如上面例子com.blue.ex。

同时,作为package来说,还有一项额外的功能就是可以打包成JAR文件,这在客户端如在利用浏览器进行下载时,远比一个一个散乱的文件传输要快!这到底正确不呢?我想你可以找一个人与你QQ聊天,然后你把一个1G的文件传输给他,第一次是压缩包,第二次是解压后的散乱文件,然后你看一下哪种传输快。

既然谈到namespace了,老实说,我想我的思维又跳跃了。在C++中的namespace中,同样有一个很奇怪的东西,叫做ADL(argument-dependent lookup),也可以称它叫做argument-dependent name lookup。这是什么呢?

namespace Test {class A {};void foo( A *&, int ) {}}int main(int argc,char* argv[]) {Test::A *a;foo(a, 0); //Right?return 0;} 

交给读者你来回答吧!

信息隐藏也差不多到此结束了,有任何想法与意见可以留言和我交流!接下来,也到了面向对象中很有趣很有说头的东西了——继承。C++的多重继承是否是万恶的?C++的virtual base class是怎么回事?Java中的继承与C++到底有何不同?这两者又是如何来对继承提供支持的?


Next

面向对象之继承(一)


Main References:

Thinking in Java 4th Edition Chapter 6; Author: Bruce Eckel

Core Java Vol.1 8th Edition Chapter 4: Authors: CAY S. HORSTMANN, GARY CORNELL