Java雜記1--類與物件
1.類、變數、方法命名遵守下列程式設計風格:
類:1.如果類名使用拉丁字母,那麼名字的首字母使用大寫,如Hello、Time等。
2.類名最好容易識別、見名知意。當類名由幾個單詞符合而成時,每個單詞的首字母使用大寫如BeijingTime、AmericanGame和HelloChina等。
變數:1.一行只宣告一個變數,方便給程式碼增添註釋內容。
如:double width; //矩形的寬double height; //矩形的高
2.變數的名字除了符合識別符號規定以外,名字的首單詞的首字母使用小寫,從第二個單詞開 始的首其他單詞字母使用大寫。
3.變數名字見名知意,,避免使用m1,n1等作為變數的名字,尤其名字中不要將小寫的英文 字母l和數字1相鄰接,很難區分。
方法:同變數。
2.方法過載
1)引數個數不同
2)引數型別不同
getArea()是一個過載方法
class Area{
float getArea(float r){
return 3.14f*r*r;
}
double getArea(float x,int y){
return x*y;
}
float getArea(int x,float y){
return x*y;
}
double getArea(float x,float y,float z){
return (x*x+y*y+z*z)*2.0;
}
}
注:方法的返回型別和引數名字不作比較。意為,如果兩個方法的名字相同,即使型別不同,也必須保證引數不同。
3.物件的引用和實體
Java的物件在堆(heap,佇列優先,先進先出)中分配記憶體,物件的引用是在棧(stack,先進後出)中分配記憶體。
也就是說,當用戶建立一個物件時,類中的成員變數在堆中分配記憶體空間,這些記憶體空間稱為該物件的實體或物件的變數,
而物件中存放著引用,該引用在棧中分配記憶體,以確保實體由該物件操作使用。
假如分別使用類的構造方法Point(int x,int y)建立兩個物件p1和p2
Point p1=new Point(12,16);
Point p2=new Point(6,18);
那麼記憶體模型如下圖所示:
圖3.1 物件記憶體模型
假如在程式中使用瞭如下賦值語句:
p1=p2;
即把p2的引用(p2在記憶體中的名字)賦給p1,因此p1和p2在本質上是一樣的。雖然在源程式中p1和p2是兩個名字,但在
系統看來它們是一個名字0xDD。系統將取消原來分配給p1的記憶體,這時,如果輸出p1.x,結果為6,因為此時p1和p2有相同的實體。
記憶體模型變成如圖2
圖3.2 p1=p2後的物件記憶體模型
一個類建立的兩個物件,如果具有相同的引用,那麼就具有完全相同的實體。沒有實體的物件稱為空物件,空物件不能使用,即不能
讓一個空物件去呼叫方法產生行為。
4.引用型別引數的傳值
當引數是引用型別時,“傳值”傳遞的是變數中存放的“引用”,而不是變數所引用的實體。
對於兩個同類型的引用型變數,如果具有同樣的引用,就會用同樣的實體,因此,如果改變引數變數所引用的實體,就會導致原變
量的實體發生同樣的變化,但是,改變引數中存在的“引用”,不會影響向其傳值的變數中存放的“引用”,反之亦然。如圖4.1。
圖4.1 引用型別引數的傳值
下面將舉例說明,此例中涉及引用型別引數,含Circle類負責建立“圓”物件、Circular類負責建立“圓錐”物件
MainClass類是主類
Circle.java
public class Circle {
double radius;
Circle(double r){
radius=r;
}
double getRadius() {
return radius;
}
void setRadius(double r) {
radius = r;
}
double getArea(){
return 3.14*radius*radius;
}
}
Circular.java
public class Circular {
Circle bottom;
double height;
Circular(Circle c,double h){ //構造方法,將Circle類的例項的引用傳遞給bottom
bottom=c;
height=h;
}
double getVolme(){
return bottom.getArea()*height/3;
}
double getBottomRadius(){
return bottom.getRadius();
}
public void setBottomRadius(double r){
bottom.setRadius(r);
}
}
MainClass.java
public class MainClass {
public static void main(String[] args) {
Circle circle=new Circle(10); //程式碼1
System.out.println("main方法中circle的引用"+circle);
System.out.println("main方法中circle的半徑"+circle.getRadius());
Circular circular=new Circular(circle,20); //程式碼2
System.out.println("circular圓錐的bottom的引用:"+circular.bottom);
System.out.println("圓錐的bottom的半徑"+circular.getBottomRadius());
System.out.println("圓錐的體積:"+circular.getVolme());
double r=1;
System.out.println("圓錐更改底圓bottom的半徑"+r);
circular.setBottomRadius(r); //程式碼3
System.out.println("圓錐的bottom的半徑"+circular.getBottomRadius());
System.out.println("圓錐的體積"+circular.getVolme());
System.out.println("main方法中circle的半徑:"+circle.getRadius());
System.out.println("main方法中circle的引用將發生變化");
circle=new Circle(100); //程式碼4 重新建立circle
System.out.println("現在main方法中circle的引用:"+circle);
System.out.println("main方法中circle的半徑:"+circle.getRadius());
System.out.println("circular圓錐的bottom的引用不影響");
System.out.println("circular圓錐的bottom的引用:"+circular.bottom);
System.out.println("圓錐的bottom的半徑:"+circular.getBottomRadius());
}
}
執行結果截圖:
解釋程式碼1~程式碼4
1.執行程式碼1後記憶體中的物件模型
Circle circle=new Circle(10);
執行此行程式碼後,記憶體中產生了一個新的circle物件,記憶體中的物件的模型如下圖所示:
圖4.2 執行程式碼1後的記憶體中的物件模型
2.執行程式碼2後的物件記憶體模型
執行程式碼2:
Circular circular=new Circular(circle,20);
記憶體中又產生了一個circular物件,並將circle物件的引用以“傳值”方式傳給circular的bottom,因此,circular物件的bottom和circle物件就有相同的實體radius
此時記憶體中的物件模型為:
圖4.3 執行程式碼2後的記憶體中的物件模型
3.執行程式碼3後的物件記憶體模型
對於兩個同類型的引用型變數,如果有相同的引用,就會有相同的實體,所以改變引數變數所引用的實體,就會導致原變數的實體發生同樣的變化
執行程式碼3:
circular.setBottomRadius(r);
使得circle和circular的bottom的實體(radius)發生了同樣的變化,如圖:
圖4.4 執行程式碼3後的記憶體中的物件模型
4.執行程式碼4後的物件記憶體模型
執行程式碼4;
circle=new Circle(100);
使得circle的引用發生了變化,重新建立了circle物件,即circle物件將獲得新的實體(circle物件的radius=1),但circle先前的實體不被釋放,因為這些實體還是
circular的bottom的實體。最初circle物件的引用是以“傳值”方式傳遞給circular的bottom的,所以circle的引用發生變化並不影響circular的bottom的引用
(bottom物件的radius值仍然為1)。物件的模型如圖:
圖4.5 執行程式碼4後的記憶體中的物件模型
總結自 《Java面向物件程式設計》第二版 耿祥義 張月平 編著
第四章 類與物件