在Java中
亦可用訪問指示符判斷出一個庫內的哪些類可由那個庫的用戶使用
若想一個類能由客戶程序員調用
可在類主體的起始花括號前面某處放置一個public關鍵字
它控制著客戶程序員是否能夠創建屬於這個類的一個對象
為控制一個類的訪問
指示符必須在關鍵字class之前出現
所以我們能夠使用
public class Widget {
也就是說
假若我們的庫名是mylib
那麼所有客戶程序員都能訪問Widget——通過下述語句
import mylib
Widget;
或者
import mylib
*;
然而
我們同時還要注意到一些額外的限制
(
) 每個編譯單元(文件)都只能有一個public類
每個編譯單元有一個公共接口的概念是由那個公共類表達出來的
根據自己的需要
它可擁有任意多個提供支撐的
友好
類
但若在一個編譯單元裡使用了多個public類
編譯器就會向我們提示一條出錯消息
(
) public類的名字必須與包含了編譯單元的那個文件的名字完全相符
甚至包括它的大小寫形式
所以對於Widget來說
文件的名字必須是Widget
java
而不應是widget
java或者WIDGET
java
同樣地
如果出現不符
就會報告一個編譯期錯誤
(
) 可能(但並常見)有一個編譯單元根本沒有任何公共類
此時
可按自己的意願任意指定文件名
如果已經獲得了mylib內部的一個類
准備用它完成由Widget或者mylib內部的其他某些public類執行的任務
此時又會出現什麼情況呢?我們不希望花費力氣為客戶程序員編制文檔
並感覺以後某個時候也許會進行大手筆的修改
並將自己的類一起刪掉
換成另一個不同的類
為獲得這種靈活處理的能力
需要保證沒有客戶程序員能夠依賴自己隱藏於mylib內部的特定實施細節
為達到這個目的
只需將public關鍵字從類中剔除即可
這樣便把類變成了
友好的
(類僅能在包內使用)
注意不可將類設成private(那樣會使除類之外的其他東西都不能訪問它)
也不能設成protected(注釋④)
因此
我們現在對於類的訪問只有兩個選擇
友好的
或者public
若不願其他任何人訪問那個類
可將所有構建器設為private
這樣一來
在類的一個static成員內部
除自己之外的其他所有人都無法創建屬於那個類的一個對象(注釋⑤)
如下例所示
//: Lunch
java
// Demonstrates class access specifiers
// Make a class effectively private
// with private constructors:
class Soup {
private Soup() {}
// (
) Allow creation via static method:
public static Soup makeSoup() {
return new Soup();
}
// (
) Create a static object and
// return a reference upon request
// (The
Singleton
pattern):
private static Soup ps
= new Soup();
public static Soup access() {
return ps
;
}
public void f() {}
}
class Sandwich { // Uses Lunch
void f() { new Lunch(); }
}
// Only one public class allowed per file:
public class Lunch {
void test() {
// Can
t do this! Private constructor:
//! Soup priv
= new Soup();
Soup priv
= Soup
makeSoup();
Sandwich f
= new Sandwich();
Soup
access()
f();
}
} ///:~
④
實際上
Java
內部類既可以是
受到保護的
也可以是
私有的
但那屬於特別情況
第
章會詳細解釋這個問題
⑤
亦可通過從那個類繼承來實現
迄今為止
我們創建過的大多數方法都是要麼返回void
要麼返回一個基本數據類型
所以對下述定義來說
public static Soup access() {
return psl;
}
它最開始多少會使人有些迷惑
位於方法名(access)前的單詞指出方法到底返回什麼
在這之前
我們看到的都是void
它意味著
什麼也不返回
(void在英語裡是
虛無
的意思
但亦可返回指向一個對象的句柄
此時出現的就是這個情況
該方法返回一個句柄
它指向類Soup的一個對象
Soup類向我們展示出如何通過將所有構建器都設為private
從而防止直接創建一個類
請記住
假若不明確地至少創建一個構建器
就會自動創建默認構建器(沒有自變量)
若自己編寫默認構建器
它就不會自動創建
把它變成private後
就沒人能為那個類創建一個對象
但別人怎樣使用這個類呢?上面的例子為我們揭示出了兩個選擇
第一個選擇
我們可創建一個static方法
再通過它創建一個新的Soup
然後返回指向它的一個句柄
如果想在返回之前對Soup進行一些額外的操作
或者想了解准備創建多少個Soup對象(可能是為了限制它們的個數)
這種方案無疑是特別有用的
第二個選擇是采用
設計方案
(Design Pattern)技術
本書後面會對此進行詳細介紹
通常方案叫作
獨子
因為它僅允許創建一個對象
類Soup的對象被創建成Soup的一個static private成員
所以有一個而且只能有一個
除非通過public方法access()
否則根本無法訪問它
正如早先指出的那樣
如果不針對類的訪問設置一個訪問指示符
那麼它會自動默認為
友好的
這意味著那個類的對象可由包內的其他類創建
但不能由包外創建
請記住
對於相同目錄內的所有文件
如果沒有明確地進行package聲明
那麼它們都默認為那個目錄的默認包的一部分
然而
假若那個類一個static成員的屬性是public
那麼客戶程序員仍然能夠訪問那個static成員——即使它們不能創建屬於那個類的一個對象
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26502.html