1. 程式人生 > 實用技巧 >Java基礎之:構造方法(構造器)與this關鍵字

Java基礎之:構造方法(構造器)與this關鍵字

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;
    }
}

注意事項

  1. 一個類可以定義多個不同的構造方法,構造方法過載 比如:我們可以再給Person類定義一個構造方法,用該方法來建立新物件的時候,只指定人名,不需要指定年齡。

  2. 如果程式設計師沒有定義構造方法,系統會自動給類生成一個預設無參構造方法(也叫預設構造方法),比如 Person (){}。 可以在Dos中使用,javap -p Person.class 反編譯,檢視編譯檔案後Person類中的構造器。

  3. 一旦定義了自己的構造方法,預設的構造方法就覆蓋了,就不能再使用預設的無參構造方法,除非顯示的定義一下,即: Person(){}; 。 建議在自己寫了有參構造方法後,預設寫上無參構造方法,避免出現報錯。

  4. 主要作用是完成對新物件的初始化(構造方法完成), 並不是建立物件。在建立新物件時(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);
    }
}