<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 5.2 Java訪問指示符 針對類內每個成員的每個定義,Java訪問指示符`public`,`protected`以及`private`都置于它們的最前面——無論它們是一個數據成員,還是一個方法。每個訪問指示符都只控制著對那個特定定義的訪問。這與C++存在著顯著不同。在C++中,訪問指示符控制著它后面的所有定義,直到又一個訪問指示符加入為止。 通過千絲萬縷的聯系,程序為所有東西都指定了某種形式的訪問。在后面的小節里,大家要學習與各類訪問有關的所有知識。首次從默認訪問開始。 ## 5.2.1 “友好的” 如果根本不指定訪問指示符,就象本章之前的所有例子那樣,這時會出現什么情況呢?默認的訪問沒有關鍵字,但它通常稱為“友好”(Friendly)訪問。這意味著當前包內的其他所有類都能訪問“友好的”成員,但對包外的所有類來說,這些成員卻是“私有”(Private)的,外界不得訪問。由于一個編譯單元(一個文件)只能從屬于單個包,所以單個編譯單元內的所有類相互間都是自動“友好”的。因此,我們也說友好元素擁有“包訪問”權限。 友好訪問允許我們將相關的類都組合到一個包里,使它們相互間方便地進行溝通。將類組合到一個包內以后(這樣便允許友好成員的相互訪問,亦即讓它們“交朋友”),我們便“擁有”了那個包內的代碼。只有我們已經擁有的代碼才能友好地訪問自己擁有的其他代碼。我們可認為友好訪問使類在一個包內的組合顯得有意義,或者說前者是后者的原因。在許多語言中,我們在文件內組織定義的方式往往顯得有些牽強。但在Java中,卻強制用一種頗有意義的形式進行組織。除此以外,我們有時可能想排除一些類,不想讓它們訪問當前包內定義的類。 對于任何關系,一個非常重要的問題是“誰能訪問我們的‘私有’或`private`代碼”。類控制著哪些代碼能夠訪問自己的成員。沒有任何秘訣可以“闖入”。另一個包內推薦可以聲明一個新類,然后說:“嗨,我是Bob的朋友!”,并指望看到Bob的`protected`(受到保護的)、友好的以及`private`(私有)的成員。為獲得對一個訪問權限,唯一的方法就是: (1) 使成員成為`public`(公共的)。這樣所有人從任何地方都可以訪問它。 (2) 變成一個“友好”成員,方法是舍棄所有訪問指示符,并將其類置于相同的包內。這樣一來,其他類就可以訪問成員。 (3) 正如以后引入“繼承”概念后大家會知道的那樣,一個繼承的類既可以訪問一個`protected`成員,也可以訪問一個`public`成員(但不可訪問`private`成員)。只有在兩個類位于相同的包內時,它才可以訪問友好成員。但現在不必關心這方面的問題。 (4) 提供“訪問器/變化器”方法(亦稱為“獲取/設置”方法),以便讀取和修改值。這是OOP環境中最正規的一種方法,也是Java Beans的基礎——具體情況會在第13章介紹。 ## 5.2.2 `public`:接口訪問 使用`public`關鍵字時,它意味著緊隨在`public`后面的成員聲明適用于所有人,特別是適用于使用庫的客戶程序員。假定我們定義了一個名為`dessert`的包,其中包含下述單元(若執行該程序時遇到困難,請參考第3章3.1.2小節“賦值”): ``` //: Cookie.java // Creates a library package c05.dessert; public class Cookie { public Cookie() { System.out.println("Cookie constructor"); } void foo() { System.out.println("foo"); } } ///:~ ``` 請記住,`Cookie.java`必須駐留在名為`dessert`的一個子目錄內,而這個子目錄又必須位于由`CLASSPATH`指定的`C05`目錄下面(`C05`代表本書的第5章)。不要錯誤地以為Java無論如何都會將當前目錄作為搜索的起點看待。如果不將一個`.`作為`CLASSPATH`的一部分使用,Java就不會考慮當前目錄。 現在,假若創建使用了`Cookie`的一個程序,如下所示: ``` //: Dinner.java // Uses the library import c05.dessert.*; public class Dinner { public Dinner() { System.out.println("Dinner constructor"); } public static void main(String[] args) { Cookie x = new Cookie(); //! x.foo(); // Can't access } } ///:~ ``` 就可以創建一個`Cookie`對象,因為它的構造器是`public`的,而且類也是`public`的(公共類的概念稍后還會進行更詳細的講述)。然而,`foo()`成員不可在`Dinner.java`內訪問,因為`foo()`只有在`dessert`包內才是“友好”的。 (1) 默認包 大家可能會驚訝地發現下面這些代碼得以順利編譯——盡管它看起來似乎已違背了規則: ``` //: Cake.java // Accesses a class in a separate // compilation unit. class Cake { 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把象這樣的文件看作那個目錄“默認包”的一部分,所以它們對于目錄內的其他文件來說是“友好”的。 ## 5.2.3 `private`:不能接觸! `private`關鍵字意味著除非那個特定的類,而且從那個類的方法里,否則沒有人能訪問那個成員。同一個包內的其他成員不能訪問`private`成員,這使其顯得似乎將類與我們自己都隔離起來。另一方面,也不能由幾個合作的人創建一個包。所以`private`允許我們自由地改變那個成員,同時毋需關心它是否會影響同一個包內的另一個類。默認的“友好”包訪問通常已經是一種適當的隱藏方法;請記住,對于包的用戶來說,是不能訪問一個“友好”成員的。這種效果往往能令人滿意,因為默認訪問是我們通常采用的方法。對于希望變成`public`(公共)的成員,我們通常明確地指出,令其可由客戶程序員自由調用。而且作為一個結果,最開始的時候通常會認為自己不必頻繁使用`private`關鍵字,因為完全可以在不用它的前提下發布自己的代碼(這與C++是個鮮明的對比)。然而,隨著學習的深入,大家就會發現`private`仍然有非常重要的用途,特別是在涉及多線程處理的時候(詳情見第14章)。 下面是應用了`private`的一個例子: ``` //: IceCream.java // Demonstrates "private" keyword 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`,所以可防止對這個類的繼承(這是第6章要重點講述的主題)。 若確定一個類只有一個“助手”方法,那么對于任何方法來說,都可以把它們設為`private`,從而保證自己不會誤在包內其他地方使用它,防止自己更改或刪除方法。將一個方法的屬性設為`private`后,可保證自己一直保持這一選項(然而,若一個引用被設為`private`,并不表明其他對象不能擁有指向同一個對象的`public`引用。有關“別名”的問題將在第12章詳述)。 ## 5.2.4 `protected`:“友好的一種” `protected`(受到保護的)訪問指示符要求大家提前有所認識。首先應注意這樣一個事實:為繼續學習本書一直到繼承那一章之前的內容,并不一定需要先理解本小節的內容。但為了保持內容的完整,這兒仍然要對此進行簡要說明,并提供相關的例子。 `protected`關鍵字為我們引入了一種名為“繼承”的概念,它以現有的類為基礎,并在其中加入新的成員,同時不會對現有的類產生影響——我們將這種現有的類稱為“基類”或者“基本類”(Base Class)。亦可改變那個類現有成員的行為。對于從一個現有類的繼承,我們說自己的新類“擴展”(`extends`)了那個現有的類。如下所示: ``` class Foo extends Bar { ``` 類定義剩余的部分看起來是完全相同的。 若新建一個包,并從另一個包內的某個類里繼承,則唯一能夠訪問的成員就是原來那個包的`public`成員。當然,如果在相同的包里進行繼承,那么繼承獲得的包能夠訪問所有“友好”的成員。有些時候,基類的創建者喜歡提供一個特殊的成員,并允許訪問派生類。這正是`protected`的工作。若往回引用5.2.2小節“`public`:接口訪問”的那個`Cookie.java`文件,則下面這個類就不能訪問“友好”的成員: ``` //: ChocolateChip.java // Can't access friendly member // in another class import c05.dessert.*; public class ChocolateChip extends Cookie { public ChocolateChip() { System.out.println( "ChocolateChip constructor"); } public static void main(String[] args) { ChocolateChip x = new ChocolateChip(); //! x.foo(); // Can't access foo } } ///:~ ``` 對于繼承,值得注意的一件有趣的事情是倘若方法`foo()`存在于類`Cookie`中,那么它也會存在于從`Cookie`繼承的所有類中。但由于`foo()`在外部的包里是“友好”的,所以我們不能使用它。當然,亦可將其變成`public`。但這樣一來,由于所有人都能自由訪問它,所以可能并非我們所希望的局面。若象下面這樣修改類`Cookie`: ``` public class Cookie { public Cookie() { System.out.println("Cookie constructor"); } protected void foo() { System.out.println("foo"); } } ``` 那么仍然能在包`dessert`里“友好”地訪問`foo()`,但從`Cookie`繼承的其他東西亦可自由地訪問它。然而,它并非公共的(`public`)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看