我們人出生的時候,有些人一出生之後再起名字的,但是有些人一旦出生就已經起好名字的。那麼我們在java裏面怎麼在對象一旦創建就賦值呢?
需求: 使用java類描述 一個嬰兒, 一種嬰兒一出生就具備了名字(白戶),還有一種嬰兒就是 出生之後纔有名字 的(黑戶)。
構造函數的作用: 給對應的對象進行初始化。
構造函數的定義的格式:
修飾符 函數名(形式參數){函數體...
}
構造函數要注意的細節:
1. 構造函數 是沒有返回值類型的。2. 構造函數的函數名必須要與類名一致。
3. 構造函數並不是由我們手動調用的,而是在創建對應的對象時,jvm就會主動調用到對應的構造函數。
4. 如果一個類沒有顯式的寫上一個構造方法時,那麼java編譯器會爲該類添加一個無參的構造函數的。
5. 如果一個類已經顯式的寫上一個構造方法時,那麼java編譯器則 不會再爲該類添加 一個無參 的構造方法。
6. 構造函數是 可以在一個類中以函數重載 的形式存在多個 的。
/*
描述一個員工類,員工具備 的屬性:id\ name \ age 。
具備的公共行爲: 工作。
要求:一旦創建一個員工對象 的時候,那麼該員工對象就要對應 的屬性值。
*/
class Employee{
int id; //編號
String name; //名字
int age; //年齡
//構造函數
public Employee(int a, String b , int c){
id =a;
name = b;
age = c;
}
public void work(){
System.out.println(name+"好好工作,努力掙錢!!");
}
}
class MyClass
{
public static void main(String[] args)
{
//創建一個員工對象
Employee e = new Employee(110,"米奇",20);
System.out.println("編號:"+ e.id+" 名字:"+e.name +" 年齡:"+ e.age);
}
}
疑問:創建對象時,jvm就會調用到對應的構造方法,那麼我們以前沒有學構造方法,那麼以前創建對象時,jvm是否 也會調用構造方法呢?如果有?構造方法從何而來呢?
會調用, java編譯器在編譯的 時候給加上去的。
jdk提供了一個java開發工具(javap.exe)給我們進行反編譯的。
javap 反編譯工具的使用格式:javap -c -l -private 類名
疑問: java編譯器添加 的無參構造方法的權限修飾符是 什麼?
與類的權限修飾是一致的。
構造函數與普通 函數的區別:
1. 返回值類型的區別:1. 構造函數是沒有返回值類型的。
2. 普通函數是有返回值類型的,即使函數沒有返回值,返回值類型也要寫上void。
2. 函數名的區別:
1. 構造函數的函數名必須要與類名一致。
2. 普通函數的函數名只要符合標識符的命名規則即可。
3. 調用方式的區別:
1. 構造函數是 在創建對象的時候由jvm調用的。
2. 普通函數是由我們使用對象調用的,一個對象可以對象多次普通 的函數,
4. 作用上的區別:
1. 構造函數 的作用用於初始化一個對象。
2. 普通函數是用於描述一類事物的公共行爲的。
//嬰兒類
class Baby{
int id; //身份證
String name; //名字
//構造函數
public Baby(int i , String n){
id = i;
name = n;
System.out.println("baby的屬性初始化完畢!!");
}
//無參 的構造函數
public Baby(){
System.out.println("無參的構造函數被調用了..");
}
//哭
public void cry(){
System.out.println(name+"哇哇哭...");
}
}
class MyClass
{
public static void main(String[] args)
{
//創建一個baby對象
Baby b1 = new Baby(110,"狗娃"); //嬰兒誕生 白戶
System.out.println("編號:"+ b1.id +" 姓名:"+ b1.name);
b1.cry();
b1.cry();
/*
//黑戶
Baby b2 = new Baby();
new Baby();
b2.id = 112;
b2.name = "狗剩";
System.out.println("編號:"+ b2.id +" 姓名:"+ b2.name);
*/
}
}
問題:要求每個小孩出生都會哭,這份代碼有兩個構造函數,如果需要每個小孩出生都要哭的話,那麼就需要在不同的構造函數中都調用cry()函數,但是這樣子的話造成了代碼重複問題,那麼怎麼解決呢?構造代碼塊。
構造代碼塊:
構造函數的作用: 給對應的對象進行初始化。
構造代碼塊的作用:給對象進行統一的初始化。
1:給對象進行初始化。對象一建立就運行並且優先於構造函數。
2:與構造函數區別
1) 構造代碼塊和構造函數的區別,構造代碼塊是給所有對象進行統一初始化, 構造函數給對應的對象初始化。
2) 構造代碼塊的作用:它的作用就是將所有構造方法中公共的信息進行抽取。
例如孩子一出生統一哭
{
構造代碼塊
}
注意: 構造代碼塊的大括號必須位於成員 位置上。
代碼塊的類別:
1. 構造代碼塊。
2. 局部代碼塊. 大括號位於方法之內。 作用:縮短局部 變量 的生命週期,節省一點點內存。
3. 靜態代碼塊 static
class Baby{
int id; //身份證
String name; //名字
//構造代碼塊...
{
//System.out.println("構造代碼塊的代碼執行了......");
}
//帶參構造函數
public Baby(int i , String n){
id = i;
name = n;
}
//無參構造方法
public Baby(){
}
public void cry(){
System.out.println(name+"哇哇哭...");
}
}
class MyClass
{
public static void main(String[] args)
{
Baby b1 = new Baby(110,"米奇");
System.out.println("編號:"+ b1.id + " 名字:"+b1.name);
/*
System.out.println("編號:"+ b1.id + " 名字:"+b1.name);
new Baby(112,"唐老鴨");
new Baby();
*/
/*
new Baby(110,"米奇");
new Baby(112,"唐老鴨");
new Baby();
*/
}
}
構造代碼塊要注意的事項:
1. java編譯器編譯一個java源文件的時候,會把成員變量的聲明語句提前至一個類的最前端。2. 成員變量的初始化工作其實都在在構造函數中執行的。
3. 一旦經過java編譯器編譯後,那麼構造代碼塊的代碼塊就會被移動構造函數中執行,是在構造函數之前執行的,構造函數的中代碼是最後執行 的。
4. 成員變量的顯示初始化與構造代碼塊 的代碼是按照當前代碼的順序執行的。
class MyClass
{
//構造函數
public MyClass(){ //構造函數
i = 300000000;
}
//構造代碼塊 //構造代碼塊的初始化
{
i = 200000000;
}
int i = 100000000; //成員變量的顯初始化
public static void main(String[] args)
{
MyClass d = new MyClass();
System.out.println("i = "+d.i);
}
}