java之類的定義和物件的建立
-
類的基本結構
如果一切都是物件,那麼是什麼決定某一類物件的行為與外觀呢?答案時“類”。類是構造物件的模板或藍圖。就像建築物與設計圖紙,通過一份設計圖紙,可以構造處建築物,而Java開發人員在編寫程式碼時,實際上是編寫類程式碼,物件只有程式執行時才存在。
當用戶建立一個Java程式時,可以通過類宣告來定義類。通常,這些類裡沒有main方法,只有一些屬性和方法。一個完整的程式,應該由若干個類組成,其中一般只有一個類有main方法。
在Java中,最簡單的類的定義語法為:
class 類名
{
//類中的程式碼
}
第一行稱為類的宣告。兩個花括號之間的部分稱為類體,類體中可以包含方法或成員變數。
例如下面程式碼定義了一個簡單的類Student。
class Student { .......}
在具體的程式設計中,一個完整的類還包含建構函式、成員變數、方法等,將在後面逐一介紹。
-
類之間的關係
在面向物件的思想中,類之間存在一下幾種常見的關係
1、USES-A 關係
“USES-A 關係” 是一種最明顯、最常見的關係,若類A中的方法操縱了類B(物件)的成員,則稱之為類A “USES-A” (用到了)類B。例如,汽車啟動前檢查汽油是否足夠,例:
class Car { private int cubage=100; public void startIsEnough() { if(cubage>80) System.out.println("汽油充足,汽車可以啟動"); else System.out.println("汽車不可以啟動"); } } public class Sample3_1 { public static void main(String[] args) { // TODO Auto-generated method stub Car c=new Car(); c.startIsEnough(); } }
在上述例子中,main方法例項化Car類後,呼叫startIsEnough()方法,形成“IS-A”關係。因為汽油儲量裝置為100,滿足儲備量充足規則,可以啟動,所以執行結果中列印了”汽油充足,可以啟動”。
2、HAS-A關係
“HAS-A”關係是一種擁有關係,若類A中有B型別的成員引用變數,則類A“HAS-A”(即擁有)型別B。例如,轎車擁有輪胎:
class Car
{
private Type t=new Type();
public Type getTypeInfo()
{
return t;
}
}
class Type
{
private String material="橡膠" ;
private String color="黑色" ;
public String getMaterial()
{
return material;
}
public String getColor()
{
return color;
}
}
public class Sample3_2
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c=new Car();
System.out.println("輪胎的顏色為:"+c.getTypeInfo().getColor());
System.out.println("輪胎的材料為:"+c.getTypeInfo().getMaterial());
}
}
通過上述程式碼可以看出“HAS-A”關係的具體含義,由於汽車物件擁有了輪胎物件,所以汽車物件也就擁有了輪胎物件中的一切可見資訊。
3、IS-A關係
在面向物件中“IS-A”的概念是基於繼承的, 旨在表達一個類是另一個類的子類。也就是說,若類A是類B子類的一種,則可以說類A “IS-A”(是一種)類B。例如,“蘋果”是“水果”的一種,則他們之間的關係為“蘋果” IS-A(是一種)“水果”。
在實際開發中需要同時用到以上介紹的幾種關係,要抓住現實世界中事物之間的實際關係來進行抽象,然後再Java世界中建立模型。如果搞錯了關係的型別,有可能影響系統的開發或維護。
-
建構函式
在建立物件時,物件的成員可以由建構函式方法進行初始化。建構函式是一種特殊的方法,它具有和他所在的類完全一樣的名字。一旦定義好一個建構函式,建立物件時就會自動呼叫它。建構函式沒有返回型別,這是因為一個類的建構函式的返回值就是這個類本身。建構函式的任務就是初始化以一個物件的內部狀態,所以用new操作符建立一個例項後,立刻就會得到一個可用的物件。例如,利用建構函式初始化汽車的各項引數:
package Car;
class Car
{
private String color;
private String brand;
//下面為建構函式,建構函式與類名相同。在建構函式中,初始化汽車的顏色和品牌
public Car()
{
this.color="黑色";
this.brand="大眾";
}
//構造方法
public String getColor()
{
return this.color;
}
public String getBrand()
{
return this.brand;
}
}
public class Sample3_3
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c=new Car();
System.out.println("汽車的顏色為:"+c.getColor());
System.out.println("汽車的品牌為:"+c.getBrand());
}
}
在上面的例子中,main方法例項化Car類時,呼叫Car類的建構函式初始化類變數。在Car類中,建構函式是不包含任何引數的。有時也需要為建構函式定義引數,方便賦值,下面的例子同時定義了兩個建構函式,分別帶引數和不帶引數:
package Car;
class Car
{
private String color;
private String brand;
//無參建構函式
public Car()
{
this.color="黑色";
this.brand="大眾";
}
//有參建構函式
public Car(String co ,String br )
{
this.color=co;
this.brand=br;
}
//構造方法
public String getColor()
{
return this.color;
}
public String getBrand()
{
return this.brand;
}
}
public class Sample3_3
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c1=new Car();
System.out.println("汽車的顏色為:"+c1.getColor());
System.out.println("汽車的品牌為:"+c1.getBrand());
Car c2=new Car("紅色","奧迪");
System.out.println("汽車的顏色為:"+c2.getColor());
System.out.println("汽車的品牌為:"+c2.getBrand());
}
}
上面說的例子當中,包含兩個建構函式,有時一個類可能有多個建構函式,每個建構函式的引數型別均不相同,多個建構函式可看作方法的過載,只能根據引數型別匹配合適的建構函式。但構造方法與普通方法不同,是一種特殊的方法,具體有以下特點:
- 構造方法的方法名必須與類名相同
- 構造方法沒有返回型別,也不能定義為void,在方法名面前不宣告方法型別
- 構造方法的主要作用是完成物件的初始化工作,它能夠把定義物件時的引數傳給物件的域
- 構造方法不能由程式設計人員呼叫,而要系統呼叫
- 構造方法可以過載,以引數的個數,型別或排列順序區分
- 一個類可以定義多個構造方法,如果在定義類時沒有定義構造方法,則編譯系統會自動插入一個無參的預設構造器,這個構造器不執行任何程式碼
-
類成員
定義了類之後,就可以在類體中宣告兩種類的成員,成員變數與成員方法。
1、成員變數的使用
成員變數就是類的屬性,類定義中的屬性指定了一個物件區別於其他物件的值。例如,學生類的定義包括年齡、姓名和班級這些屬性,每個物件的這些屬性都有自己的值。所有由類定義建立的物件都共享類的方法,但是,它們都具有各自屬性變數的副本。
成員變數有時也可以稱為例項變數,其定義寫在類體中:
class Student
{
public int stuAge;
public String stuName;
public String stuClass;
//年齡,姓名,班級
}
public class Sample3_5
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Student s1=new Student();
Student s2=new Student();
//為s1賦值
s1.stuAge=21;
s1.stuName="張三";
s1.stuClass="200801";
//為s2賦值
s2.stuAge=23;
s2.stuName="李四";
s2.stuClass="200802";
System.out.println(s1.stuName+' '+s1.stuAge+' '+s1.stuClass);
System.out.println(s2.stuName+' '+s2.stuAge+' '+s2.stuClass);
}
}
有點像C語言中的結構體,從上述例子中可以看出,兩個物件成員變數有其各自的值,互不影響,new操作建立物件後將返回其引用值,一般在new操作完成後都將其返回的物件引用賦值給一個引用,也就是讓引用指向建立的物件。如果只是用new操作建立物件不讓某個引用指向該物件,則物件自建立後就不能對其進行訪問了。因為在Java中,訪問物件只能通過指向物件的引用來實現。
2、成員變數的初始值
變數型別 | 預設值 |
boolean | false |
char | '\u000' |
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0D |
物件引用型 | null |
物件引用型成員變數,其初始值為null,表示此引用沒有指向任何物件,這裡需要注意的是,字串(String)型別空引用(null)與空字串不同,空引用表示沒有指向任何物件,而空字串表示內容為空的字串物件。
-
物件的建立
有了類就可以利用其建立物件了,在Java中建立物件很簡單,只要用new關鍵字即可,由類建立物件的過程中稱為例項化,每個物件是類的一個例項,如學生類是對什麼是學生做定義,而張三、李四是學生類的例項。
建立物件與基本型別的宣告類似,首先說明建立物件的所屬類名,然後為物件的名稱,例如 Student s=new Student();Student 為物件所屬類,s為物件名稱,通過new為新物件建立記憶體空間。與變數相比,物件的記憶體控制元件要大很多,因為物件是以類為模板建立的具體實列,具有屬性和方法,例如s物件具有班級、姓名等屬性,具有上課、下課等方法。如果要呼叫該物件則需要用點運算子' . '連線需要的屬性和方法,例如s.name=“李四”;。