Java基礎之:構造方法(構造器)與this關鍵字
前面我們在建立人類的物件時,是先把一個物件建立好後,再給他的年齡和姓名屬性賦值。如果現在要求,在建立人類的物件時,就直接指定這個物件的年齡和姓名,該怎麼做? 這時就可以使用構造方法/構造器。
基本語法
[訪問修飾符] 方法名 (引數列表){ 構造方法體; }
說明:
1) 構造器的修飾符可以預設
2) 構造器沒有返回值(若前面寫了返回值,就變成了成員方法)
3) 方法名 和 類 名字必須一樣
4) 引數列表 和 成員方法一樣的規則
5) 構造器的呼叫有系統JVM 來呼叫,當 我們建立新的物件,使用 new 的時候系統JVM來呼叫。
構造方法又叫構造器(constructor),是類的一種特殊的方法,它的主要作用是完成對新物件的初始化。
在建立一個類的新物件時,系統會自動的呼叫該類的構造方法完成對新物件的初始化。
簡單案例
public class ConTest { public static void main(String[] args) { //傳統寫法 // Person p1 = new Person(); // p1.name = "jack"; // p1.age = 20; //構造器 Person p2 = new Person("tom", 30); System.out.println(p2.name + " " + p2.age); } } class Person { String name; int age; //構造器 public Person(String pName, int pAge) { System.out.println("構造器被呼叫...."); name = pName; age = pAge; } }
注意事項
-
一個類可以定義多個不同的構造方法,構造方法過載 比如:我們可以再給Person類定義一個構造方法,用該方法來建立新物件的時候,只指定人名,不需要指定年齡。
-
如果程式設計師沒有定義構造方法,系統會自動給類生成一個預設無參構造方法(也叫預設構造方法),比如 Person (){}。 可以在Dos中使用,javap -p Person.class 反編譯,檢視編譯檔案後Person類中的構造器。
-
一旦定義了自己的構造方法,預設的構造方法就覆蓋了,就不能再使用預設的無參構造方法,除非顯示的定義一下,即: Person(){}; 。 建議在自己寫了有參構造方法後,預設寫上無參構造方法,避免出現報錯。
-
主要作用是完成對新物件的初始化(構造方法完成), 並不是建立物件。在建立新物件時(JVM完成),系統自動的呼叫該類的構造方法。
簡單案例
/** 可以在Dos中使用,javap -p Person.class 反編譯,檢視編譯檔案後Person類中的構造器。 在定義的Person類中新增兩個構造器: 第一個無參構造器:利用構造器設定所有人的age屬性初始值都為18 第二個帶pName和pAge兩個引數的構造器:使得每次建立Person物件的同時初始化物件的age屬性值和name屬性值。 */ import java.util.Scanner; public class Constructor_Class { public static void main(String[] args){ Person p1 = new Person(); Person p2 = new Person("小范",20); p1.print(); p2.print(); } } class Person { int age; String name; //習慣在定義有參構造器時,寫出無參的構造器 public Person(){ age = 18; } //有參構造器 public Person(String pName,int pAge){ name = pName; age = pAge; } public void print(){ System.out.println("name:"+name+" , age:" + age); } }
物件建立流程分析(重點)
案例:
class Person{ int age=90; String name; Person(String n,int a){ name=n; age=a; } } Person p=new Person("小倩",20);
流程分析:
1) 載入 Person 類 (Person.class), 只會載入一次
2) 在堆中 開資料空間 , 得到一個地址
3) 資料的初始化(不斷改變 堆空間中 age 與 name 的值)
(1) 預設初始化 age = 0, name = null
(2) 顯式初始化 age = 90 , name = null
(3) 構造器初始化 age= 20 name = “小倩”
4) 把 堆中的地址,返回給 p
5) 使用
this關鍵字
java虛擬機器會給每一個物件分配一個this關鍵字。this關鍵字指向物件自己。
例:小范說 我的 年齡是 20歲 , 小黃說 我的 年齡是 18歲。
在這句話中出現了兩個"我的",但它們分別指向不同的物件。這就是this關鍵字。
使用方法簡單案例
public class ThisTest { public static void main(String[] args) { Person p1 = new Person("小范", 20); System.out.println("p1的地址(hashcode=)" + p1.hashCode()); p1.showInfo(); System.out.println("======================"); Person p2 = new Person("小黃", 18); System.out.println("p1的地址(hashcode=)" + p2.hashCode()); p2.showInfo(); //哪個物件呼叫,this就代表哪個物件 // p1.m1(); // p2.m1(); } } class Person{ public String name; // null public int age; //0 //形參,本質就是 區域性變數 public Person(String name, int age){ //通過hashCode()可以基本區分物件地址,返回一個整數 this.name = name; this.age = age; System.out.println(this.name + " this.hashCode=" + this.hashCode()); } public void m1() { System.out.println(); System.out.println(this.name + " this.hashCode=" + this.hashCode()); } public void showInfo(){ System.out.println(name + "\t" + age + "\t"); } }
this關鍵字細節
public class ThisDetail { public static void main(String[] args) { AA a = new AA(); a.m2(); System.out.println(a.name); // smith AA a2 = new AA("king"); System.out.println(a2.name); // king } } class AA { int age = 10; String name = "tom"; public AA() { //構造器1 //訪問構造方法(構造器)語法:this(引數列表) this("smith"); // this 可以呼叫其它構造器, 需要在構造器內 } public AA(String name) { //this用於區分當前類的成員和區域性變數 this.name = name; } public void m1() { //this關鍵字可以用來訪問本類的屬性、方法、構造器 System.out.println(this.age); } public void hi() { System.out.println("hi"); } public void m2() { System.out.println("m2()"); //訪問成員方法的語法:this.方法名(引數列表); this.hi(); // 可以訪問 本類的 hi(); } }
細節說明
1) this關鍵字可以用來訪問本類的屬性、方法、構造器
2) this用於區分當前類的成員和區域性變數
3) 訪問成員方法的語法:this.方法名(引數列表);
4) 訪問構造方法(構造器)語法:this(引數列表);
5) this不能在類定義的外部使用,只能在類定義的方法中使用
簡單案例
/** 1) 類House , 要求寫兩個構造器 2) 構造器1 (address, price) 3) 構造器2 (address, price ,ares) 4) 分別使用不同的構造器,並輸出 房子資訊 */ import java.util.Scanner; public class Constructor_House { public static void main(String[] args){ House h1 = new House("111",100); House h2 = new House("222",200,120); h1.print(); h2.print(); } } class House { String address; int price; int ares; public House(){} public House(String address,int price){ this.address = address; this.price = price; } public House(String address,int price,int ares){ // this.address = address; // this.price = price; this(address,price); //可以這樣寫,呼叫其他構造器幫助我們賦值 this.ares = ares; } public void print(){ System.out.println("房子地址:"+ this.address + " 價格:" + this.price + " 面積:" + this.ares); } }