1. 程式人生 > 其它 >構造器、this關鍵字、setter和getter

構造器、this關鍵字、setter和getter

構造器、this關鍵字、setter和getter

構造器

我們一直在學習怎麼封裝class,一個class封裝好之後的目的一般是建立例項物件,我們其實已經做過了。

Dog dog = new Dog();

new 一個物件的時候到底發生了什麼事情呢?

  1. java在new一個物件的時候,會先檢視物件所屬的類有沒有被載入到記憶體,如果沒有的話,就會先通過類的許可權定名來載入,這個過程我們後邊聊。
  2. 載入並初始化類完成後,再進行物件的建立工作。

我們先聊聊建立的過程:

  1. 在堆區分配物件需要的記憶體。
  2. 對所有例項變數賦預設值。
  3. 執行構造方法,比如我們可以使用構造方法賦值。(不太準確,以後會慢慢補充)
  4. 在棧區定義引用變數,然後將堆區物件的地址賦值給它。

構造方法,也叫構造器,會在new物件的時候主動被呼叫。

但是,事實上,我們並沒有看到任何構造方法。

每個java類,會預設送你一個構造方法,這個方法它是這個樣子的:

public Dog(){        
}

我們可以寫出來,也可以不寫,這個構造方法什麼都沒做,我們可以想辦法讓它做一些事情,比如:

public Dog(){
    name = "teddy";
    age = 12;
}

public static void main(String[] args) {
    Dog dog = new Dog();
    System.out.println(dog.name);
    System.out.println(dog.age);
}

我們並沒有呼叫這個方法啊:
但是,結果卻出來了:
    teddy
    12

當然如果我們想自己按照自己的意願去構造例項,我們還可以定義這樣的構造器:

同時new的時候就要傳遞引數了:

public Dog(String name,int age){
    System.out.println("驗證構造方法被呼叫的時機:【"+ name + "】被建立!");
    this.name = name;
    this.age = age;
}

public static void main(String[] args) {
    Dog dog = new Dog("jinmao",23);
    System.out.println(dog.name);
    System.out.println(dog.age);
}

結果:
    驗證構造方法被呼叫的時機:【jinmao】被建立!
    jinmao
	23

此時,如果我們把那個沒有引數的構造器刪除,

你會發現已經不能這麼去new物件了。

【注】一旦自己寫了構造器,系統將不再贈送,所以我們一般【會自己補充上】。

#6、this關鍵字

  • 記住一點:每一個方法都會預設傳入一個變數叫this,它永遠指向呼叫它的【當前例項】。

#(1)this訪問屬性和方法

寫段程式碼:

//構造方法和其他方法一樣可以過載,可以有引數,名字必須和類名一樣,不能有一點區別
public Dog(String name){
    System.out.println("驗證構造方法被呼叫的時機:【"+ name + "】被建立!");
    this.name = name;
}

public void eat(){
    // this也可以在成員方法中使用
    System.out.printf("【%s】再吃骨頭。",this.name);
}

public static void main(String[] args) {
    //直接new物件看看new的時候是不是呼叫了構造方法,事實證明是的
    new Dog("哈士奇").eat();
}

一個方法只有在呼叫的時候,才能明確方法中的【this】具體指向哪個例項物件。

我們可以使用this訪問當前物件的方法和屬性。

#(2)this訪問構造器

還可以訪問當前類的構造器:

//構造方法和其他方法一樣可以過載,可以有引數,名字必須和類名一樣,不能有一點區別
public Dog(String name){
    System.out.println("驗證構造方法被呼叫的時機:【"+ name + "】被建立!");
    this.name = name;
}

public Dog(){
    this("default");
}

如果我們使用無參構造會傳入一個預設值,這就是典型的案例

this當做構造器只能放在第一行

#7、setter和getter

我們之前呼叫一個例項物件的屬性的時候,都是 dog.name 但事實上,java程式設計師從來不會這麼幹。

我們有這樣的規定,所有的屬性必須私有化,使用setter和getter賦值或者取值,

public class Dog {
    
    //有哪些特點
    //定義狗有顏色這個屬性
    private String color;
    //定義狗有種類這個屬性
    private String type;
    //定義狗有年齡這個屬性
    private int age;
    
    //java約定使用setter和getter方法進行屬性的取值和賦值
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //..狗還有很多屬性和方法,我們無法一一列舉
}

為什麼呢?

  • getter方法能夠按照客戶的期望返回格式化資料。
  • setter方法可以限制和檢驗setter方法傳入的引數,隱藏物件內部資料結構。
  • 屬性不具備多型性。

舉個例子:

public class Girl {
    
    private int age;

    public int getAge() {
        // 你問我多大了,真實年齡大於18歲,都是18歲
        if(this.age > 18){
            return 18;
        }
        return age;
    }

    public void setAge(int age) {
        // 每過一年,如果我超過了18歲,我永遠是18歲。
        if(age > 18){
            this.age = 18;
        }
        this.age = age;
    }
}

所以,正確的定義一個類,一定是

  • 所有的屬性私有化。
  • 每個屬性都有對應的getter和setter放。

這是規矩,你得遵守。

package com.ydlclass;

public class Girl {
    //第一塊成員變數
    private String name;
    private int age;
    private int weight;
    //第二塊構造器
    public Girl(){
    }
    public Girl(String name){
        this.name = name;
    }
    public Girl(int age,int weight){
        this.age = age;
        this.weight = weight;
    }
    //第三塊成員方法
    int feeling = 0;
    public void happy(int feeling){
        if (feeling >= 60){
            System.out.println(name+"很開心!");
        }else if (feeling >= 0 & feeling < 60){
            System.out.println(name+"很平靜!");
        }else {
            System.out.println(name+"很傷心!");
        }
    }
    //第四塊get和set
    public void setName(String name){
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setAge(int age){
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }

    public void setWeight(int weight){
        this.weight = weight;
    }
    public int getWeight(){
        return this.weight;
    }
}
package com.ydlclass;

public class Test {
    public static void main(String[] args) {
        Girl girl = new Girl();
        girl.setName("安妮");
        girl.setAge(19);
        girl.setWeight(50);
        System.out.println("女孩的名字叫:"+girl.getName());
        System.out.println("她的年齡:"+girl.getAge()+"歲");
        System.out.println("她的體重:"+girl.getWeight()+"kg");
        girl.happy(60);
    }
}

女孩的名字叫:安妮
她的年齡:19歲
她的體重:50kg
安妮很開心!

Process finished with exit code 0