2021年6月23日 星期三

JAVA 物件導向的概念-01 用類別創造物件,是為了偷懶

   假設我要在程式中鍵入藍斯洛特的資料,我會建立幾個屬性,例如名字、身高、體重、生日,那麼建立完了以後,如果我又要再建立桂妮薇兒的資料時,又得再建立名字、身高、體重、生日一次。那是多麼麻煩啊!

  在 JAVA 中,我們不會這麼做,而是先建造一個人的類別,我們就稱它為人類別好了,在這個類別裡面我們建好了人所擁有的屬性,再用人類別創造藍斯洛特和桂妮薇兒的物件,一創造出來,他們就擁有人的屬性了。同樣的,我們可以用人類別創造其他的人物件,他們也都會擁有人的屬性,這方便多了。

  基於上段的說明,人類別內所建的屬性最好是所有人都會有的共通屬性,例如只要是人就一定有名字、性別、生日等。以下是類別和主程式的程式碼,記得都要創建在該 project 的 src 資料裡面。

類別的程式
// 編寫人:Lancelot Cheng
public class Person {
// 這個類別是人類共有屬性的集合,理想上是人都會有的屬性,不過我這邊把它當成遊戲人物。

// 字串名字
String name;
// 整數年齡
int age;

// 字串稱號,宇串武器,整數力量,整數傷害
String title, weapon;
int power, hurt;

static String king = "亞瑟";
// static 在記憶體上是唯一的位置,當類別被使用到時就產生了,不用到 new 出物件才產生。
// 也就是說 king 是 person 物件與其子類的物件所共享的變數。

static public final String species = "人類";
// 此變數是 static final ,即代表它是所有 person 物件及其子物件所共享的常數,即唯一且不能修改。

// 以下方法用來顯示物件的資料。
void showFile() { // 靜態方法。
System.out.println( "名:" + name +",年紀:" + age + ",稱號:" +
title + ",力量:" + power +",種族:"+ species + ",效忠:" + king);
}

// 以下方法是物件的傷害能力。
void attack() { // 靜態方法。
System.out.println("使用" + weapon);
hurt = power*power;
System.out.println("給予敵人傷害" + hurt);
}

// 以下是按滑鼠右鍵,然後點 Generate,再選 Getter and setter 產生的。
// 只要前面的變數有設好,它會顯示選項,讓你選擇哪些變數要有 Getter 和 Setter。
// 有設定 Getter and setter 的變數才能在主程中得到與設定其值。


public static String getKing() {
return king;
}

public static void setKing(String king) {
Person.king = king;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

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

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getWeapon() {
return weapon;
}

public void setWeapon(String weapon) {
this.weapon = weapon;
}

public int getPower() {
return power;
}

public void setPower(int power) {
this.power = power;
}

public static String getSpecies() {
return species;
}
}
忘了說明封裝,利用類別產生出來的物件,裡面的有哪些屬性,屬性又為何,我們不得而知,此特性稱為封裝,方式就在那些變數前加上 private ,如果想要得到其值或是設定其值,就必須設定 getter and setter 。你可能會覺得很奇怪,你都看得到程式碼,如何會不知道其屬性呢?依情況的不同,你可能會需要和別人合作,而相互之間都想保留自己程式碼中的機密資訊,對方給你的可能是執行檔案,而非程式碼,你所能得到與設定的值就只有對方有設定 getter and setter 的變數。

Elton 補充說明:封裝就是不希望任何人可以透過任意語法來存取物件中的資料,而我們只統一對外公開2個出入口:getter、setter。任何人只能用上面的getter/setter來存取物件中的數據,進而統一存取規範、亦達到資料保護。

主程式
// 編寫人:Lancelot Cheng
public class PersonInformation {

public static void main(String[] args) {

Person lancelot = new Person(); // 創造名為 lancelot 的 person 物件
lancelot.setName("藍斯洛特"); //
lancelot.setAge(18);
lancelot.setTitle("湖上騎士");
lancelot.setWeapon("樹枝");
lancelot.setPower(1000);

lancelot.showFile();
lancelot.attack();

System.out.println();

Person guinevere = new Person(); // 創造名為 guinevere 的 person 物件
guinevere.setName("桂妮薇爾");
guinevere.setAge(17);
guinevere.setTitle("人間的海倫"); // 她好像沒有稱號,我亂編的。
guinevere.setWeapon("玫瑰刺劍");
guinevere.setPower(800);

guinevere.showFile();
guinevere.attack();

System.out.println();

Person.setKing("愛情"); // 靜態變數也稱類別變數,故可以直接用類別名稱操作。
        System.out.println("在 Person.setKing 更改後。");
lancelot.showFile(); // 兩個人效忠的對像會一起改變,理由見 Person 類別內變數 king 的註解。
guinevere.showFile();
}
}

執行結果

名:藍斯洛特,年紀:18,稱號:湖上騎士,力量:1000,種族:人類,效忠:亞瑟
使用樹枝
給予敵人傷害1000000

名:桂妮薇爾,年紀:17,稱號:人間的海倫,力量:800,種族:人類,效忠:亞瑟
使用玫瑰刺劍
給予敵人傷害640000

在 guinevere.setKing 更改後。
名:藍斯洛特,年紀:18,稱號:湖上騎士,力量:1000,種族:人類,效忠:愛情
名:桂妮薇爾,年紀:17,稱號:人間的海倫,力量:800,種族:人類,效忠:愛情

Process finished with exit code 0

沒有留言:

張貼留言