Java 程式設計()  第九章 繼承性與多形性運用  上一頁    下一頁

 

9-3 覆蓋繼承成員

內容:

  • 9-3-1 繼承性的覆蓋

  • 9-3-2 範例研討:員工薪資資料建檔

  • 9-3-3 自我挑戰:建立客戶會員資料

9-3-1 繼承性的覆蓋

子類別成員的名稱與父類別成員相同時,則表示覆蓋了父類別成員,如果需要取用原父類別成員則利用 super this 區分。譬如父類別有 addr 變數成員,子類別除了繼承父類別的 addr 成員之外,也自行再宣告一個 addr 變數成員(兩者名稱相同)。基本上,子類別下的 addr 會覆蓋了父類別的 addr,但事實上還是存在兩個不同變數(記憶體位址不同),吾人可利用 super.addr(父類別)與 this.addr(子類別或 addr 即可)來分辨。

9-3-2 範例研討:員工薪資資料建檔

A)程式功能:Ex9_2.java

展鵬行銷公司期望建立一套員工薪資管理系統,目前思考該系統針對某位員工資料為:員工姓名、員工代號、底薪、加班時數、戶籍地址與通訊地址等 5 種屬性。其中依勞基法規定底薪不可以低於 15800 元,每月加班時數不可超過 45 小時。登錄資料時如有違背規定,系統會重複要求重新輸入。設計完成資料屬性後,請編寫一簡單程式,測試系統是否可做資料輸入與輸出,期望操作介面如下:

G:\Examples\chap12\Ex9_2>java Ex9_2

**** 建立員工薪資資料  ****

請輸入員工姓名 =>劉美女

員工代號 (700 ~ 900) =>740

戶籍地址 =>高雄市三民區

通訊地址 =>台北市內湖區

底薪 = >50000

加班時數 = >30

 

**** 列印員工薪資資料 *****

員工代號            戶籍地址        通訊地址

(740  劉美女 )   50000    30        高雄市三民區    台北市內湖區

B)製作技巧研討:

公司裡大多希望各系統之間的資料能夠相容,對於爾後資料搬移會比較容易。之前我們幫展鵬公司設計了人事管理系統(Ex9_1 範例),也制定了公司內人事資料的標準格式(Employee 類別)。因此,希望員工薪資資料也是由人事資料延伸下來。Employee 類別包含有:員工代號(ID)、身分證號(SID)、姓名(name)、性別(sex)、服務部門(depart)、職位(position)、電話(tel)與地址(addr)。然而依照薪資管理系統,需要每位員工的:員工代號(ID)、姓名(name)、底薪(payment)、加班時數(extra)、通訊地址(addr)與戶籍地址(addr);其中員工代號、姓名與戶籍地址可以繼承自 Employee 類別,其他屬性可能需要自行宣告產生(Salary 類別,如圖 9- 7 所示)。但有兩個地址名稱相同,一個是父類別的 addr 代表戶籍地址,另一者是子類別的 addr 代表通訊地址,因此必須利用 super.addr addr 作之間的區別。依照上述的概念,我們製作了宣告員工薪資資料的 Salary 類別,再編寫主程式(Ex9_2.java)引用該類別,測試其結果如何。

9-7 Salary 類別產生

C 程式範例:Salary.java

依照上述的概念,我們製作了員工薪資類別 Salary,也繼承了員工基本資料類別 Employee,原始程式如下:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

//Salary.java

 

/* Employee.class 需於同目錄下 */

class Salary extends Employee {

 

    String addr;               // 通訊地址

    private int payment;         //     > 15800

    private int extra;            // 加班時數 < 45

 

    /*** 宣告物件方法 ***/

    int setPayment(int pay) {   //設定底薪方法, 1: 正常, 0: 錯誤

         if (pay < 15800) {

             System.out.printf("底薪不可低於 15800 \n");

             return 0;

         }

         else {

             payment = pay;

             return 1;

         }

     }

     int getPayment() {      // 讀取底薪方法

         return payment;

     }

     int setExtra(int ex) {    // 設定加班時數, 1: 正常, 0: 錯誤

         if (ex > 45) {

             System.out.printf("加班時數不可超過 45 小時\n");

             return 0;

         }

         else {

             extra = ex;

             return 1;

         }

     }

     int getExtra() {        // 取得加班時數方法

         return extra;

     }

     /* 存取父類別變數成員的方法 */

     void setHomeAddr(String ad) {

        super.addr = ad;

     }

     String getHomeAddr() {

        return super.addr;

     }   

}

Salary 類別包含下列成員:( 僅擷取本範例所需部份)

(1) 變數成員IDnamesuper.addr(以上繼承自 Employee),以及 paymentExtra addr(通訊地址,以上是自行宣告)。

(2) 方法成員setPayment()getPaymentsetExtra()getExtrasetHomeAddr()、以及 getHomeAddr(),最後兩個方法是設定與取得父類別的 addr 屬性(戶籍地址)

D)程式範例:Ex9_2.java

設定完成 Salary 類別之後,吾人製作一個簡單程式(Ex9_2.java),功能是輸入員工薪資資料,再印出輸入的結果如何;其中儲存員工資料的物件,即是由 Salary 類別生產生。

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

//Ex9_2.java

 

/* Salary.class 需於同目錄下 */

import java.io.*;

public class Ex9_2 {

   public static void main(String args[]) throws IOException {

       BufferedReader keyin = new BufferedReader(new

                              InputStreamReader(System.in));

       Salary sal = new Salary();

       String tempS;

       int value;

       double m;

       System.out.printf("**** 建立員工薪資資料  ****\n");

 

       System.out.printf("請輸入員工姓名 =>");

          sal.name = keyin.readLine();

       System.out.printf("員工代號 (700 ~ 900) =>");

          sal.ID = Integer.parseInt(keyin.readLine());

       System.out.printf("戶籍地址 =>");

           tempS = keyin.readLine();

           sal.setHomeAddr(tempS);

       System.out.printf("通訊地址 =>");

           sal.addr = keyin.readLine();

       System.out.printf("底薪 = >");

           value = Integer.parseInt(keyin.readLine());

           while (sal.setPayment(value) == 0) {

                System.out.printf("請重新輸入 =>");

                value = Integer.parseInt(keyin.readLine());

           }

       System.out.printf("加班時數 = >");

           value = Integer.parseInt(keyin.readLine());

           while (sal.setExtra(value) == 0) {

                System.out.printf("請重新輸入 =>");

                value = Integer.parseInt(keyin.readLine());

           }

 

        System.out.printf("\n**** 列印員工薪資資料 *****\n");

        System.out.printf("員工代號        ");

        System.out.printf("\t戶籍地址\t通訊地址\n");

        System.out.printf("(%d  %s )   %d    %d",

                   sal.ID, sal.name, sal.getPayment(), sal.getExtra());

        System.out.printf("\t%s    %s\n", sal.getHomeAddr(), sal.addr);

    }

}

9-3-3 自我挑戰:建立客戶會員資料

(A) 程式功能:PM9_2.java

『展鵬網路行銷公司』為了增進與客戶之間的關係,而制定了會員制度;首先思考以下策略:

(1) 客戶累積購買金額超過 3萬元,可選擇加入會員,一般會員(C 級)購買商品打九折。

(2) 新進會員有效期為 1 ,如當年累積金額超過 3 萬元者,會員有效期延長 1 年。

(3) 如果一般會員(C 級)當年購買累積金額超過 3 萬元後,自動升級為白金會員(B 級),購物打八折。

(4) 如果白金會員當年購物超過 6 萬元後,自動升級為鑽石會員(A 級),購物打七折。

為了客戶隱私權問題,系統不可任意查閱客戶身份證字號與出生日期,但有時候公司還是需要知道客戶身份證號碼。經過多方的考慮,客服部目前規劃會員的基本資料為:身份證號碼(SID)、會員號碼(SID)、姓名(name)、累積金額(buying)、有效日期(validDate)、地址(addr)與電話(tel),其中身份證號碼需要特定程序才可以查閱或修改,以保持客戶的隱私權。另外,會員號碼由一個英文字母連結 5 個數字,英文字 ABC 代表會員級數(鑽石、白金或一般),5 個數字表示會員號碼(不變的)。則可能會員代號是 A00001 ~ C10000,設計這樣的目的是會員身份可能隨購買金額改變(上升或下降)。期望操作介面如下:

G:\Examples\chap12\PM9_2>java PM9_2

**** 建立會員基本資料  ****

請輸入客戶姓名 =>張智慧

身分證字號 = >K121834561

購買金額 = >70023

請輸入會員代號 (10000 ~ 99999) =>34021

有效日期 (//) = >2009/3/12

地址 =>台中市中港路

電話 (##-#######) =>04-2349871

 

**** 列印會員基本資料 *****

身分證號    代號   姓名  有效日期   累積金額     

(K121834561 B34021 張智慧 2009/3/12)    70023   04-2349871  台中市中港路

(B) 製作技巧提示:

依照公司規定,客戶需累積購買金額後,才可以成為會員,享有折扣優惠,由此可見,會員資料大多來自客戶資料,設計會員類別(Member)時,也需繼承自客戶類別(Customer,請參閱範例 PM9_1)。Customer 類別具有:身份證號(SID)、姓名(name)、性別(sex)、生日(birthDate)、購買商品(product)、金額(buying)、地址(addr)與電話(tel)。如 Member 類別繼承自 Employee 類別,可引用:姓名(name)、身份證號(SID)、購買金額(buying)、電話(tel)與地址(addr),再自行宣告會員代號(SID)與有效日期(validDate)即可。但身份證號與會員代號變數名稱相同,吾人以 super.SID SID 區分(如圖 9- 8 所示)。

9-8 Member 類別產生

另外,系統要求會員代號是由會員類別(ABC),與 5 個數字的會員號碼組成(10000 ~ 99999),又會員類別是由累積購買金額判定。因此,輸入會員資料時,僅輸入會員號碼與累積金額,系統會自動產生會員代號(A10000 ~ C10000)。

吾人依照上述概念,建立 Member 類別,編寫一主程式引用該類別,再輸入會員資料看系統是否可行。

C)程式範例提示:Member.java

Member 類別產生的過程是 Personal => Customer => Member,因此 Member 類別裡可引用原 Personal Customer 所宣告的任何成員(變數或方法)。

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

//Member.java

 

/* Customer.class 需於同目錄下 */

 

class Member extends Customer {

 

    private String SID;              // 會員代號

    String validDate;                // 有效日期

 

    /*** 宣告物件方法 ***/

    int setSID(String M_SID) {  //設定會員代號方法, 1: 正常, 0: 錯誤

         String level = "";

         int flag;

         if (buying < 30000) {

             System.out.printf("請先輸入購買金額或\n");

             System.out.printf("購買金額需超過 3 萬元\n");

             flag=0;

         }

         else if (buying <60000 ) {

             level = "C";

             flag = 1;

         }

         else if (buying <90000 ) {

             level = "B";

             flag=1;

         }

         else {

             level = "A";

             flag = 1;

         }

         if (flag == 0)

             return 0;           // 執行失敗

         SID = level.concat(M_SID);    // 字串連結方法

         return 1;               // 執行成功

     }

     String getSID() {      // 讀取會員代號方法

         return SID;

     }

     int setPerSID(String S_SID) {    // 設定身分證號方法

         int k = super.setSID(S_SID);   // 呼叫父類別方法

         return k;

     }

     String getPerSID() {             // 讀取身份證號方法

        String S_SID = super.getSID();  // 呼叫父類別方法

        return S_SID;

     }

}

其中,super.setSID()(第 40~43 行)呼叫父類別(Personal 類別)方法,功能是設定 SID 變數成員(身份證號)內容,執行正常則傳回 1;否則傳回 0。然而,Member 類別可直接引用成員有:

(1) 變數成員:姓名(name)、有效日期(validDate)、購買金額(buying)、電話(tel)與地址(addr)。

(2) 方法成員:設定身份證號(int setPerSID(String))、讀取身份證號(String getPerSID())、設定會員代號(int setSID(String))與讀取會員代號(String getSID)。

D)程式範例提示:PM9_2.java

吾人可利用 Member 類別宣告會員物件,再依序輸入資料與輸出會員所有資料,請參考 Ex9_2.java 範例製作本範例的主程式(PM9-2.java),本書不再贅言。

 

翻轉工作室:粘添壽

 

Java 程式設計(二) 含物件導向

 

 

翻轉電子書系列: