JAVA程式員必讀:基礎篇(5)
來源:互聯網
上載者:User
程式|程式員
JAVA程式員必讀:基礎篇時間:2001/09/13 13:31作者:ZSC 太平洋網路學院
2.4執行個體和類成員
2.4.1理解執行個體和類成員
下面詳細討論一下執行個體和類成員,具體涉及變數和方法以及類變數和方法:
你這樣聲明一個成員變數,比如在類Myclass中有一個float型的aFloat:
class MyClass {
float aFloat;
}
這樣你就聲明一個執行個體變數。每次你建立一個類的執行個體的時候,系統就為執行個體建立了類的每一個執行個體變數的副本。你可以從對象中訪問對象的執行個體變數。
執行個體變數跟類變數是不一樣的,類變數示使用靜態修改量來聲明的。不管類建立了多少個執行個體,系統為每個類變數分配了類變數。系統為類變數分配的記憶體是在它第一次調用類的時候發生的。所有的執行個體共用了類的類變數的相同副本。你可以通過執行個體或者通過類本身來訪問類變數。
它們的方法是類似的:你的類可以有執行個體方法和類方法。執行個體方法是對當前對象的執行個體變數進行操作的,而且訪問類變數。另外一個方法,類方法不能訪問定義在類中的執行個體變數,除非它們建立一個新的對象並通過對象來訪問它們。同樣,類方法可以在類中被調用,你不必需要一個執行個體來調用一個類方法。
預設地,除非其它的成員被指定,一個定義在類中成員就是一個執行個體成員。這個在下面定義的類有一個執行個體變數,有一個整型的x,兩個執行個體方法x和setX,它們設定其它對象以及查詢x的數值。
class AnIntegerNamedX {
int x;
public int x() {
return x;
}
public void setX(int newX) {
x = newX;
}
}
每次你從一個類執行個體化一個新的對象,你可以得到每個類的執行個體變數的副本。這些副本都是跟新對象有關係的。因此,每次你從這個類執行個體化一個新的AnIntegerNamedX對象的時候,你得以得到跟新的AnIntegerNamedX對象有關的新副本。
一個類的所有執行個體共用一個執行個體方法的相同的實行;所有的AnIntegerNamedX執行個體都共用x和setX的相同執行。這裡注意,兩個方法x和setX是指對象的執行個體變數x。但是,你可能會問:如果所有AnIntergerNamedX共用x和setX的相同執行,會不會造成模稜兩可的狀態?答案當然是:不是。在執行個體方法中,執行個體變數的名字是指當前對象的執行個體變數,假如執行個體變數不是由一個方法參數來隱藏的。這樣在x和setX中,x就等價於這個x,而不會造成混亂。
對於AnIntegerNamedX外部的對象如果想訪問x,它必須通過特定的AnIntegerNamedX的執行個體來實現。假如這個程式碼片段處在其它對象的方法中。它建立了兩種不同類型的AnIntegerNamedX,它設定了x為不同的數值,然後顯示它們:
AnIntegerNamedX myX = new AnIntegerNamedX();
AnIntegerNamedX anotherX = new AnIntegerNamedX();
myX.setX(1);
anotherX.x = 2;
System.out.println("myX.x = " + myX.x());
System.out.println("anotherX.x = " + anotherX.x());
這裡注意,代碼使用setX來為myX設定x的值,而直接給anotherX.x指定一個數值。不管用什麼方法,代碼是在操作兩個不同的x副本:一個包含在myX對象中一,另外一個包含在anotherX對象中。其輸出是用以下程式碼片段來實現的:
myX.x = 1
anotherX.x = 2
上面代碼顯示了類AnIntegerNamedX的每一個執行個體有自己執行個體變數x的副本以及每個x有自己的數值。
你可以在聲明成員變數的時候,指定變數是一個類變數而不是一個執行個體變數。相似地,你可以指定方法是一個類方法而不是一個執行個體方法。系統在第一次調用類來定義變數的時候建立了一個類變數的副本。所有的類執行個體共用了類變數的相同副本。類方法可以只操作類變數,它們不能訪問定義在類中的執行個體變數。
為了指定一個成員變數為一個類變數,你可以使用static關鍵字。比如,我們可以修改一下上面的AnIntegerNamedX類,使得x變數現在是一個類變數:
class AnIntegerNamedX {
static int x;
public int x() {
return x;
}
public void setX(int newX) {
x = newX;
}
}
現在設定它們的x數值並顯示不同的輸出:
myX.x = 2
anotherX.x = 2
這次的輸出不同,是因為x現在是一個類變數,所以就只有這個變數的副本,它是被AnIntegerNamedX的所有執行個體所共用的,包括myX和anotherX。當你在其它執行個體中調用setX的時候,你可以為所有的AnIntegerNamedX的所有執行個體改變x的數值。
同樣,當我們聲明一個方法的時候,你可以指定方法為類方法而不是執行個體方法。類方法只可以在類變數中進行操作,並且不能訪問定義在類中的所有執行個體變數。
為了指定方法為類方法,你可以在方法聲明處使用static關鍵字。下面,我們再次來修改AnIntegerNamedX類,使它的成員變數x為一個執行個體變數,以及它的兩個方法為類方法:
class AnIntegerNamedX {
int x;
static public int x() {
return x;
}
static public void setX(int newX) {
x = newX;
}
}
當你想編譯這個版本的AnIntegerNamedX,編譯器就會顯示如下的錯誤: AnIntegerNamedX.java:4: Can't make a static reference to
nonstatic variable x in class AnIntegerNamedX.
return x;
^
出現這些錯誤的原因是類方法不能訪問執行個體變數,除非方法先建立AnIntegerNamedX的一個執行個體並且通過它來訪問變數。
下面我們修改一下AnIntegerNamedX,讓x變數成為類變數:
class AnIntegerNamedX {
static int x;
static public int x() {
return x;
}
static public void setX(int newX) {
x = newX;
}
}
現在為x設定數值,並列印出x數值:
myX.x = 2
anotherX.x = 2
再一次,我們通過myX來改變x,並將它改變為AnIntegerNamedX的其它執行個體。
執行個體成員和類成員之間的另外一個差別是類成員可以從類本身進行訪問。你不必執行個體化類來訪問它的類成員。下面讓我們編寫一段代碼來直接從AnIntegerNamedX類中訪問x和setX:
. . .
AnIntegerNamedX.setX(1);
System.out.println("AnIntegerNamedX.x = " + AnIntegerNamedX.x());
. . .
值得一提的是,你現在已經不用再建立myX和anotherX了。你可以設定x並直接AnIntegerNamedX類中檢索x。你不能利用執行個體成員來處理它,你只能從一個對象來調用執行個體方法並且只可以從對象中訪問執行個體變數。而你可以從類的執行個體或者從類本身來訪問類變數和方法。
上