类的访问权限

   在JAVA中,访问权限修饰词也可以用于确钉库中的哪些类对于该库的使用者是可用的。如果希望某各类可以为某个客户端程序员所用,就可以通过把关键字public作用于整个类的定义来达到目的。这样做甚至可以控制客户端程序员是否能创建一个该类的对象。

   为了控制某各类的访问权限,修饰词必须出现于关键词class之前,因此可以向下面这样声明:

  public class WIDGET{

  现在如果库的名字是access。那么任何客户端程序员都可以通过下面的声明访问Widget:

   import access.Widget;

   或  import access.*;

   然而,这里还有一些额外的限制;

   1,每个编译单元(文件)都只能有一个public类。这表示,每个编译单元都有单一的公共接口,用public类来表现。该接口可以按要求包含众多的支持包访问权限的类。如果某个编译单元内有一个以上的public类,编译器就会给出出错信息。

   2,public类的名称必须完全和含有该编译单元的文件名称相匹配,包括大小写。所以对于Widget而言,文件的名称必须是Widget.class。如果不匹配,同样将得到编译时错误。

   3,虽然不是很常用,但编译单元内完全不带public类也是可能的。这种情况下,可以随意对文件命名。(尽管随意命名会使人们在阅读和维护代码是产生混淆)

   如果获取了一个在access内部的类,用来完成Widget或是其他在access中的public类所要执行的任务。将会出现什么样的情况呢?你不想自找麻烦去为客户端程序员创建说明文档,而且你认为不久可能会想要完全改变所有方案并将旧版本一起删除,代之以一种不同的版本。为了保留此灵活性,需要确保客户端程序员不会依赖于隐藏在access之中的任何特定实现细节。为了达到这一点,只需将public从类中拿掉,这个类就拥有了包访问权限。(该类只可以用于该包之中。)

   练习1:根据描述access和Widget的代码片段创建类库。在某个不属于access类库的类中创建一个Widget实例。

   在创建一个包访问权限的类时,仍旧是在将该类的域声明为private是才有意义-应尽可能的总是将域指定为私有的,但是通常来说,将于类(包括访问权限)相同的访问权限赋予方法也是很合理的。既然一个有包访问权限的类通常只能被用于包内,那么如果对你有强制要求,在此种情况下,编译器会告诉你,你只需将这样的类的方法设定为public就可以了。

   请注意,类及不可以是private的(这样会使得除该类之外,其他任何类都不可以访问他),也不可以是protectod的,所以对于类的访问权限,仅有两个选择,包访问权限和public。如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器都指定为private,从而阻止任何人创建该类的对象,但是有一个例外,就是你在该类的static成员内部可以创建。下面是一个示例;

public class Soup1 {
    private Soup1() {
    };

    public static Soup1 makgSoup1() {
        return new Soup1();
    }
}
public class Lunch {
    void testPrivate(){
//      Can't do this!private constructor
//        Soup1 soup1 = new Soup1();
    }
    void testStatic(){
        Soup1 soup1 = Soup1.makgSoup1();
    }
    void testSingleton(){
        Soup2 soup2 = Soup2.makeSoup2();
    }
}
 

   Soup1类和Soup2类展示了如何通过将所有的构造器指定为private来阻止直接创建某个类的实例。请一定要牢记,如果没有明确的至少创建一个构造器的话,就会帮你创建一个默认的构造器(不带有任何参数的构造器)。如果我们自己编写了默认的构造器,那么就不会动创建它了。如果把该构造器指定为private,那么就谁也无法创建该类的对象了。但是现在别人该怎么样使用这个类呢?上面的例子就给出了两个选择:在Soup1中,创建一个static方法,他创建一个新的Soup1对象并返回一个对它的引用。如果想要在返回引用之前在Soup1上做一些额外的工作,或是如果想要记录到底创建了多少个Soup1对象(可能要限制其数量),这种做法将会是大有裨益的。

  Soup2用到了所谓的设计模式,该模式在别的书中有所介绍,这种特定的模式被称为singleton(单例),这是因为你失重只能创建它的一个对象,Soup2类的对象是作为Soup2的一个static private成员而创建的,所以有且仅有一个,而且除非是通过public方法access(),否则是无法访问到它的。

   正如前面所提到的,如果没能为类访问权限指定一个修饰符,他就会默认得到包访问权限,这就意味着该类的对象可以由包内任何其他类来创建,但在包外则是不行的。(一定要记住,相同目录下的所有不具有明确package声明的文件,都被视作是该目录下默认包的一部分。)然而,如果该类的某个static成员是publci的话,则客户端程序员仍旧可以调用该static成员,尽管他们并不能生成该类的对象。

   练习8,校方示例Lunch.java的形式,创建一个名为ConnectionManager的类,该类管理一个元素为Connection对象的固定数组。客户端程序员不能知己诶创建Connectiong对象,而只能通过ConnectionManager中的某个static方法来获取它们。当ConnectionManager之中不再有对象时,他会返回Null引用。在main()之中检测这些类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值