控制对类成员的访问

在对封装的支持中,类具备两大益处.第一,类将数据和操作数据的代码连接在一起.第二,类提供了用来控制访问成员的途径,而这一点正式我们这里要讨论的.
尽管Java的方法有些复杂,然而从本质上讲,Java只有两大类成员:公有成员和私有成员.公有成员尅自动的被定义在类以外的代码访问,到目前为止,我们讨论的都是这种类型的成员.私有成员只能被该类定义的其他方法访问.通过使用私有成员可以实现对访问的控制.
限制对类成员的访问是面向对象程序设计的基础,因为这有利于防止对象的误用.只允许通过一系列定义良好的方法直接向私有成员赋值.同时,还可以精确的控制如何以及何时使用对象中的数据.因此,当正确实现对类成员的访问控制后,类就可以创建可悲使用的黑箱,其内部动作不会被任意篡改.
到目前为止,还不必担心如何控制类成员的访问,因为Java默认的访问设置允许程序中的其他代码任意访问类的成员(即默认访问设置本质上是公有的),尽管这对于简单的类而言十分方便,但是这个默认设置对于许多实际情况并不合适.下面你将看到如何使用Java的访问控制功能.
Java的访问修饰符
成员的访问控制是通过使用三个访问修饰符来实现的,他们分别是:public,private和protected.如前所述,如果没有使用访问修饰符,则使用默认访问设置.在本章中,我们关注的是public和private.protected修饰符在涉及继承时才会用到.
当public修饰符修饰类成员时,程序中的任何代码都可以访问该成员.定义在其他类中的方法也可以访问.
当某个类中的一个成员被指定为private时,只有该类的其他成员可以访问该成员.因此,一个类中的方法不能访问另一个类中的private成员.
在程序没有分包的情况下,默认访问设置(没有使用访问修饰符)与public相同.包(package)本质上是类的集合.包既是一种组织形式,又是一种访问控制功能.
访问修饰符位于成员的类型说明之前,即他是一条成员声明语句的开始,下面是一些示例:
public String errMsg;
private accountBalance bal;
其中errMsg是公有的,可以被任何代码访问.
bal是私有的,只能被本类的成员访问.
为了了解访问控制如何应用于更实际的示例,请考虑下面这个实现”软失效”的int数组的程序.在数组中,越界访问是被禁止的,因为这样做可避免发生运行时异常.这是依靠把数组封装为类的私有成员来实现的,以便只允许通过成员来访问数组.使用这种方法,可以使任何对数组的越界访问温和失效,以防止这种异常发生.软失效数组是由FailSoftArray类来实现的,如下所示:
public class test2
{
    // @param args
    public static void main(String args[])
    {
     FailSoftArray fs = new FailSoftArray(5,-1);
     
     System.out.println("Fail quietly:");
     for(int i=0;i<(fs.length * 2); i++)
     {
         if(!fs.put(i, i*10))
         {
             System.out.println("index : "+i+"  out of bounds");
         }
     }
    }
}
class FailSoftArray
{
    private int a[];
    private int errval;
    public int length;
    
    /*construct array given its size and the  value to
     return if get() fails.*/
    public FailSoftArray(int size,int errv)
    {
        a = new int[size];
        errval = errv;
        length = size;
    }
    
    //return value at given index
    public int get(int index)
    {
        if(indexOK(index)) return a[index];
        return errval;
    }
    
    //put a value at an index.return false on  failure
    public boolean put(int index,int val)
    {
        if(indexOK(index))
        {
            a[index] = val;
            return true;
        }
        return false;
    }
    
    //return true if index is within bounds
    private boolean indexOK(int index)
    {
        if(index >= 0 && index < length) return  true;
        return false;
    }
}
输出:
Fail quietly:
index : 5 out of bounds
index : 6 out of bounds
index : 7 out of bounds
index : 8 out of bounds
index : 9 out of bounds