继续上一篇的内容。其实写这种东西也挺没意思的,搞C++的一般不看这东西,搞Java的又觉得这东西太浅。而且这种文章又有教唆C++程序员学习Java或者Java程序员学习C++的嫌疑,容易被两家的坚定支持者反感。那也是实在没有办法的事情,我一直以为,要想了解一个人,最好的办法是从人家的角度思考问题。关于Java和C++的比较,当年那些Java设计者们也应该经过了一番仔细思索吧,那么就让我继续自不量力的揣摩一下这些先贤的独特思维吧。
C++中的访问控制是简单清晰的,主要语法要点如下:
- 访问控制有public,protected,private三种
- 访问控制可以修饰成员变量,成员函数和基类
- 访问控制的语义public(公开的),protected(仅向子类公开),private(私有的)
- 访问控制是自由的,无论是内部类,局部类等各种情况,只要是修饰成员变量,成员函数和基类就随便写,而且语义不变
- 访问控制可以被有限度的破坏,这就是friend关键字的作用,但是这种破坏是被严格限制的,必须是被破坏的类主动申请,否则门都没有
Java中的访问控制就有点乱了,主要语法要点如下:
- 访问控制有public,protected,默认,private四种
- 访问控制可以修饰成员变量,成员函数和类(注意不是基类,C++中不能修饰单个类的权限,而Java中不能修饰基类的权限)
- 访问控制的语义public(公开的),protected(向同包和子类公开),默认(向同包公开),private(私有的),什么是包?简单的说就是同一目录下所有文件中定义的类。也就是说只要在一个目录下,什么protected和默认权限全是废纸。如果要打个比方就是,向同包公开就相当于只要大家都住在同一个小区里,除了你自己私有的东西就全是大家的。什么?你和老婆的结婚照?你留给你儿子的学费?别废话,统统公有。简直是进入了共产主义社会。
- 顶层类不能用protected和private修饰,所谓的顶层类就是没有基类的类(严格的说还有Object基类),这规则也有些霸道,凭什么允许默认就不允许protected
- 外部类可以访问内部类的所有东西,即使内部类里private的也不行,那意思就好像是说:”小娘子,如今落在我手心里了,你就从了吧“。除非内部类本身就声明为private的,对于这种贞洁烈女谁也没辙,不过这也从一个极端走到了另一个极端,外部类根本不能访问内部类的任何东西了,即使内部类里public的也不行
- 内部类可以访问外部类的所有东西,即使外部类private的也不行,真是来而不往非君子啊,现在该内部类翻身做主了,那架势,整一个”怎么样?日防夜防,家贼难防吧“
- 外部方法可以访问局部类的所有东西,即使局部类里private的也不行,又是一个落入贼人手中的小女子啊,而且这次连声做贞洁烈女的机会也没有了,局部类不允许public,protected,private修饰,只能算默认了
- 局部类可以访问外部类的所有东西,即使外部类里private的也不行,又是一个家贼难防的例子,不过这家贼也太过分了吧,本来以为局部类只能在所属方法的铁笼子里关着,结果连方法所属的类也无法幸免了
规则8的示例代码:
class
D
{
private int a;
public void test()
{
class Inner
{
public int m;
private int n;
}
Inner in = new Inner();
in.m = 10 ;
in.n = 20 ;
a = 100 ;
ttt();
}
private void ttt()
{
}
}
{
private int a;
public void test()
{
class Inner
{
public int m;
private int n;
}
Inner in = new Inner();
in.m = 10 ;
in.n = 20 ;
a = 100 ;
ttt();
}
private void ttt()
{
}
}
总结一下吧:
C++的访问控制是简单清晰的,当然它也要承认访问控制可能被破坏,于是把选择的权利交给了程序员自己,引入了friend关键字。
Java的访问控制是复杂模糊的,当然它也要解决访问控制被破坏的问题,但是可能它觉得friend的方式过于暴力,还是要多利用编译器本身的能力增加一些多余的控制,并以此为手段减少代码出错的可能。但是看看这一堆的规则吧,先不去管编译器是否抱怨了,至少程序员理解起来可就费劲了,而且我们有的选择吗?再次验证了Java对程序员的信任程度是远远不及C++对程序员的信任程度的。这是两种世界观的不同。