範圍
外觀
| 導航 類和物件 主題: |
類的範圍,變數或方法的範圍是其可見性和可訪問性。可見性或可訪問性意味著您可以從給定位置使用該專案。
方法引數在整個方法內可見,但在方法外部不可見。
程式碼清單 3.14:Scope.java
public class Scope {
public void method1(int i) {
i = i++;
method2();
int j = i * 2;
}
public void method2() {
int k = 20;
}
public static void main(String[] args) {
method1(10);
}
}
|
在 程式碼清單 3.14 中,i 在整個 method1 方法內可見,但在 method2 和 main 方法中不可見。
區域性變數在其聲明後可見,直到建立區域性變數的塊結束。
程式碼部分 3.50:區域性變數。
{
...
// myNumber is NOT visible
{
// myNumber is NOT visible
int myNumber;
// myNumber is visible
{
...
// myNumber is visible
}
// myNumber is visible
}
// myNumber is NOT visible
...
}
|
您肯定已經注意到,在本手冊中使用的類的方法宣告開始處的 public、protected 和 private 等詞。這些關鍵字在 Java 語言語法中稱為 訪問修飾符,它們定義了給定專案的範圍。
- 如果一個類具有 public 可見性,則該類可以被程式中的任何地方引用。
- 如果一個類具有 protected 可見性,則該類只能在定義該類的包中被引用。
- 如果一個類具有 private 可見性(只有當該類定義為巢狀在另一個類中時才可能發生),則該類只能在外部類中被訪問。
- 如果一個變數定義在 public 類中,並且它具有 public 可見性,則該變數可以透過其定義的類在應用程式中的任何地方被引用。
- 如果一個變數具有 protected 可見性,則該變數只能在子類和同一個包中透過其定義的類被引用。
- 如果一個變數具有 package 可見性,則該變數只能在同一個包中透過其定義的類被引用。
- 如果一個變數具有 private 可見性,則該變數只能在其定義的類中被訪問。
- 如果一個方法定義在 public 類中,並且它具有 public 可見性,則該方法可以透過其定義的類在應用程式中的任何地方被呼叫。
- 如果一個方法具有 protected 可見性,則該方法只能在子類和同一個包中透過其定義的類被呼叫。
- 如果一個方法具有 package 可見性,則該方法只能在同一個包中透過其定義的類被呼叫。
- 如果一個方法具有 private 可見性,則該方法只能在其定義的類中被呼叫。
介面方法和介面始終是 public。您無需指定訪問修飾符。它將預設設定為 public。為了清晰起見,建議使用 public 關鍵字。
同樣,在介面中定義的所有成員變數在類中繼承後,預設將變為 static final。
| 類 | 巢狀類 | 方法或成員變數 | 介面 | 介面方法簽名 | |
|---|---|---|---|---|---|
public
|
從任何地方可見 | 與其類相同 | 與其類相同 | 從任何地方可見 | 從任何地方可見 |
protected
|
N/A | 其類及其子類 | 其類及其子類,以及其包 | N/A | N/A |
| package | 僅從其包可見 | 僅從其包可見 | 僅從其包可見 | N/A | N/A |
private
|
N/A | 僅從其類可見 | 僅從其類可見 | N/A | N/A |
粗體表示預設情況。
可見性的一般準則是隻使成員具有必要的可見性。如果成員只需要私有,不要將其設定為公有。
這樣做,您可以重寫類並更改所有私有成員而不會出現編譯錯誤,即使您不知道所有將使用您的類的類,只要您不更改公有成員的簽名。
通常,最好將資料設定為私有或受保護的。對資料的訪問由setter和getter方法控制。這使程式設計師能夠控制對資料的訪問,允許他們檢查和處理無效資料。
程式碼段 3.51:封裝。
private String name;
/**
* This is a getter method because it accesses data from the object.
*/
public String getName() {
return name;
}
/**
* This is a setter method because it changes data in the object.
*/
public boolean setName(String newName) {
if (newName == null) {
return false;
} else {
name = newName;
return true;
}
}
|
在程式碼段 3.51中,setName()方法僅當新名稱不為空時才會更改name的值。因為setName()有條件地更改了名稱,所以最好返回一個布林值,讓程式知道更改是否成功。
測試您的知識
問題 3.15:考慮以下類。
問題 3.15:Question15.java
public class Question15 {
public static final int QKQKQKQK_MULTIPLIER = 2;
public int ijijijijijijijijijAwfulName = 20;
private int unununununununununCrummyName = 10;
private void mememememememeUglyName(int i) {
i = i++;
tltltltltltltltltlBadName();
int j = i * QKQKQKQK_MULTIPLIER;
}
public void tltltltltltltltltlBadName() {
int k = ijijijijijijijijijAwfulName;
}
public static void main(String[] args) {
mememememememeUglyName(unununununununununCrummyName);
}
}
|
列出此類的欄位和方法,這些欄位和方法可以在不更改甚至不知道客戶端類的情況下重新命名。
答案
unununununununununCrummyNamemememememememeUglyName()
每個公有欄位或方法都可以被客戶端類直接呼叫,因此如果欄位或方法有新名稱,此類將返回編譯錯誤。