1.使用C语言的程序员可能习惯于在没有任何限制下访问所有东东,这不是说不好,可能在个人英雄时代是非常好的,可是现在的软件工程动不动就数十万行代码,早已不是单个程序员所能做的了,现在讲的是TeamWork(团队合作),为了解决多个程序员之间的命名和程序之间的沟通问题,C++提出了访问控制和命名空间的概念,访问控制也是面向对象中实现隐藏的主要手段.
为什么要隐藏?
先谈点,具体可以去研究面向对象的程序设计,
“进行面向对象的设计时,一项基本的考虑是:如何将发生变化的东西与保持不变的东西分隔开。”
这一点对于库来说是特别重要的。那个库的用户(客户程序员)必须能依赖自己使用的那一部分,并知道一旦新版本的库出台,自己不需要改写代码。而与此相反,库的创建者必须能自由地进行修改与改进,同时保证客户程序员代码不会受到那些变动的影响。
为达到这个目的,需遵守一定的约定或规则。例如,库程序员在修改库内的一个类时,必须保证不删除已有的方法,因为那样做会造成客户程序员代码出现断点。然而,相反的情况却是令人痛苦的。对于一个数据成员,库的创建者怎样才能知道哪些数据成员已受到客户程序员的访问呢?若方法属于某个类唯一的一部分,而且并不一定由客户程序员直接使用,那么这种痛苦的情况同样是真实的。如果库的创建者想删除一种旧有的实施方案,并置入新代码,此时又该怎么办呢?对那些成员进行的任何改动都可能中断客户程序员的代码。所以库创建者处在一个尴尬的境地,似乎根本动弹不得。
为解决这个问题,Java推出了“访问指示符”的概念,允许库创建者声明哪些东西是客户程序员可以使用的,哪些是不可使用的。这种访问控制的级别在“最大访问”和“最小访问”的范围之间,分别包括:public,“友好的”(无关键字),protected以及private。根据前一段的描述,大家或许已总结出作为一名库设计者,应将所有东西都尽可能保持为“private”(私有),并只展示出那些想让客户程序员使用的方法。这种思路是完全正确的,尽管它有点儿违背那些用其他语言(特别是C)编程的人的直觉,那些人习惯于在没有任何限制的情况下访问所有东西。到这一章结束时,大家应该可以深刻体会到Java访问控制的价值。
这一点对于库来说是特别重要的。那个库的用户(客户程序员)必须能依赖自己使用的那一部分,并知道一旦新版本的库出台,自己不需要改写代码。而与此相反,库的创建者必须能自由地进行修改与改进,同时保证客户程序员代码不会受到那些变动的影响。
为达到这个目的,需遵守一定的约定或规则。例如,库程序员在修改库内的一个类时,必须保证不删除已有的方法,因为那样做会造成客户程序员代码出现断点。然而,相反的情况却是令人痛苦的。对于一个数据成员,库的创建者怎样才能知道哪些数据成员已受到客户程序员的访问呢?若方法属于某个类唯一的一部分,而且并不一定由客户程序员直接使用,那么这种痛苦的情况同样是真实的。如果库的创建者想删除一种旧有的实施方案,并置入新代码,此时又该怎么办呢?对那些成员进行的任何改动都可能中断客户程序员的代码。所以库创建者处在一个尴尬的境地,似乎根本动弹不得。
为解决这个问题,Java推出了“访问指示符”的概念,允许库创建者声明哪些东西是客户程序员可以使用的,哪些是不可使用的。这种访问控制的级别在“最大访问”和“最小访问”的范围之间,分别包括:public,“友好的”(无关键字),protected以及private。根据前一段的描述,大家或许已总结出作为一名库设计者,应将所有东西都尽可能保持为“private”(私有),并只展示出那些想让客户程序员使用的方法。这种思路是完全正确的,尽管它有点儿违背那些用其他语言(特别是C)编程的人的直觉,那些人习惯于在没有任何限制的情况下访问所有东西。到这一章结束时,大家应该可以深刻体会到Java访问控制的价值。
2.Java的访问控制和C++的不同之处
针对类内每个成员的每个定义,Java访问指示符poublic,protected以及private都置于它们的最前面——无论它们是一个数据成员,还是一个方法。每个访问指示符都只控制着对那个特定定义的访问。这与C++存在着显著不同。在C++中,访问指示符控制着它后面的所有定义,直到又一个访问指示符加入为止
3."友好的"
Java的类中如果没有指明访问控制符,那么默认的访问权限是当前的包,l也就是当前包的所有类可以访问到这个“友好的”成员;(友好访问使所有的类在一个包下好像有意义的组织了)
package myjava.control;
pubic class AccessControlDemo
{
public AccessControlDemo(){
System.out.println("This is AccessControlDemo");
}
String getString() //友好的
{
return "This is function getString";
}
}
AccessControlDemo.java必须驻留在名为control的一个子目录内,而这个子目录又必须位于由CLASSPATH指定的myjava目录下面.不要错误地以为Java无论如何都会将当前目录作为搜索的起点看待。如果不将一个“.”作为CLASSPATH的一部分使用,Java就不会考虑当前目录
4.public:接口访问
使用public关键字时,它意味着紧随在public后面的成员声明适用于所有人,特别是适用于使用库的客户程序员
使用public关键字时,它意味着紧随在public后面的成员声明适用于所有人,特别是适用于使用库的客户程序员
import myjava.control.*;
public class Demo{
public Demo() {
System.out.println("Demo constructor");
}
public static void main(String[] args) {
AccessControlDemo a=new AccessControlDemo // 创建AccessControlDemo对象
public class Demo{
public Demo() {
System.out.println("Demo constructor");
}
public static void main(String[] args) {
AccessControlDemo a=new AccessControlDemo // 创建AccessControlDemo对象
a.getString(); //此行出错了,getString()只能被control包内的类访问
}
}
}
5.默认包
class Cake {
public static void main(String[] args) {
Pie x = new Pie();
x.f();
}
}
public static void main(String[] args) {
Pie x = new Pie();
x.f();
}
}
在位于相同目录的第二个文件里:
//: Pie.java // The other class class Pie { void f() { System.out.println("Pie.f()"); } }
最初可能会把它们看作完全不相干的文件,然而Cake能创建一个Pie对象,并能调用它的f()方法!通常的想法会认为Pie和f()是“友好的”,所以不适用于Cake。它们确实是友好的——这部分结论非常正确。但它们之所以仍能在Cake.java中使用,是由于它们位于相同的目录中,而且没有明确的包名。Java把象这样的文件看作那个目录“默认包”的一部分,所以它们对于目录内的其他文件来说是“友好”的
6.private(私有的)
private关键字意味着除非那个特定的类,
而且从那个类的方法里,否则没有人能访问那个成员。同一个包内的其他成员不能访问private成员,
这使其显得似乎将类与我们自己都隔离起来。另一方面,也不能由几个合作的人创建一个包。所以private允许我们自由地改变那个成员,同时毋需关心它是否会影响同一个包内的另一个类。
默认的“友好”包访问通常已经是一种适当的隐藏方法;请记住,对于包的用户来说,是不能访问一个“友好”成员的。这种效果往往能令人满意,因为默认访问是我们通常采用的方法。对于希望变成public(公共)的成员,我们通常明确地指出,令其可由客户程序员自由调用。
而且作为一个结果,最开始的时候通常会认为自己不必频繁使用private关键字,因为完全可以在不用它的前提下发布自己的代码(这与C++是个鲜明的对比)。然而,随着学习的深入,
大家就会发现private仍然有非常重要的用途,特别是在涉及多线程处理的时候
private示例程序
class Sundae { private Sundae() {} static Sundae makeASundae() { return new Sundae(); } } public class IceCream { public static void main(String[] args) { //! Sundae x = new Sundae(); Sundae x = Sundae.makeASundae(); } }
这个例子向我们证明了使用private的方便:有时可能想控制对象的创建方式,
并防止有人直接访问一个特定的构建器(或者所有构建器)。在上面的例子中,我们不可通过它的构建器创建一个Sundae对象;
相反,必须调用makeASundae()方法来实现.
此时还会产生另一个影响:由于默认构建器是唯一获得定义的,而且它的属性是private,所以可防止对这个类的继承7.protected(受保护的)
protected设置的访问控制主要用于对类的继承中,等讲到继承的时候再说吧