5-4 物件陣列的運用
內容:
5-4-1 物件陣列的宣告
VIDEO
雖然利用二維陣列也可以描述真實環境,但陣列內所有欄位的資料型態必須相同,如此一來,所能描述的功能會受到很大的限制。一般非物件導向(如 C 語言),利用結構陣列來擴充結構變數的功能,使其能描述多個屬性相同的真實現象;同樣的, Java 也可以利用物件陣列來表示多個屬性相同的真實現象。宣告語法如下(如圖 5-8 所示):
(如圖 5-8
所示):
物件陣列宣告語法
範
例
類別
宣告
class class_name {
…..
}
class Employee {
….
}
物件陣列
宣告
class_name[] object_name;
object_name = new class_name[n];
Employee[] worker;
worker = new Employee[20];
物件
產生
object_name[k]
= new class_name();
…
object_name[k].membe r= value;
worker[k] = new Employee();
….
worker[k].ID = 71209;
(1) 敘述『 class_name[] object_name;』(如 Employee[] worker;)。宣告產生類別 class_name 的物件陣列,名稱為 object_name。
(2) 敘述『 object_name = new class_name[n];』(如 worker = new Employee[20];)。預留產生 n 個元素的物件陣列。
(3) 敘述『 object_name[k] = new class_name();』(如 worker[k] = new Employee();)。 產生 class_name 類別的物件,填入物件陣列的第 k 個元素內。
(4) 敘述範例『 worker[k].ID = 71209;』。將數值 71209 填入陣列物件的第 k個元素的 ID 變數成員內。
圖 5-13 物件陣列的宣告與產生
5-4-2 範例研討:簡單薪資管理系統
VIDEO
( A ) 程式功能: Ex5_3.java
請幫志明電器製造公司建立一套薪資管理系統,允許輸入多筆員工資料(員工代號、姓名、服務部門、底薪與職務加級),並印出員工薪資表,包含有:員工代號、姓名、服務部門、薪資總額、扣繳稅額( = 總額 * 0.1)與應領金額( = 薪資總額 – 扣繳稅額)。期望操作介面如下:
D:\Java2_book\chap5\Ex5_3>javac Ex5_3.java
D:\Java2_book\chap5\Ex5_3>dir/b
Employee.class
Ex5_3.class
Ex5_3.java
D:\Java2_book\chap5\Ex5_3>java Ex5_3
是否繼續輸入員工資料
(yes/no) =>yes
*****
輸入員工資料
*****
輸入員工姓名
=> 羅大仙
輸入所屬部門
=> 製造課
輸入員工代號
=>720
輸入員工底薪
=>50000
輸入薪資加級
=>12000
是否繼續輸入員工資料
(yes/no) =>yes
*****
輸入員工資料
*****
輸入員工姓名
=> 張真人
輸入所屬部門
=> 業務課
輸入員工代號
=>610
輸入員工底薪
=>70000
輸入薪資加級
=>12000
是否繼續輸入員工資料
(yes/no) =>no
*****
印出員工薪資表
*****
員工資料
薪資總額
預扣稅額
應領薪資
羅大仙
(720
製造課 )
62000 6200 55800
張真人
(610
業務課 )
82000 8200 73800
( B )製作技巧研討:
首先必須設計員工薪資各種屬性的資料型態,並將其宣告成類別( class Employee {…}),經過編譯後會產生一個獨立的中介碼( Employee.class)。再利用此類別宣告產生物件陣列( worker[]),期望員工資料儲存方式如圖 5-10 所示;每一行表示一筆員工資料,各個欄位表示所描述員工的屬性,但並非二維陣列的元素,而是描述員工物件的變數成員。
圖 5-14 物件陣列範例
假設系統最高可以儲存 20 筆員工資料,又系統可選擇連續輸入多筆資料,因此吾人必須利用 while 迴圈判斷是否超過界線,或繼續輸入資料;另外利用 k 變數紀錄目儲存了幾筆資料,或願意繼續輸入資料的話,則再產生一個物件變數填入 k 所指的陣列元素上( worker[k] = new Employee();)。輸入完畢後,再依照 k 所紀錄的資料數量,分別計算薪資總額( = 底薪 + 職務加級)、扣繳稅額( = 薪資總額 * 0.1)與應領薪資( = 薪資總額 – 扣繳稅額),並輸出到螢幕上。
( C ) 程式範例:
圖 5-15 Ex5_3 程式架構
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
49
50
51
52
53
54
55
56
57
58
59
//Ex5_3.java
/*
請建立一套薪資管理系統,允許輸入員工資料,並印出薪資表
*/
import java.util.*;
class Employee { //
員工資料類別
int ID; //
員工代號
String name; //
員工姓名
String depart; //
服務部門
int payment; //
底
薪
int duty; //
職務加級
}
public class Ex5_3 {
public static void main(String args[]){
Scanner keyin = new Scanner(System.in);
Employee[] worker;
worker = new Employee[20];
int value, tax, k=0;
String sel, temp;
System.out.printf(" 是否繼續輸入員工資料
(yes/no) =>");
sel = keyin.nextLine();
while(sel.equals("yes") && (k <20)) {
worker[k] = new Employee();
System.out.printf("*****
輸入員工資料
*****\n");
System.out.printf(" 輸入員工姓名
=>");
worker[k].name = keyin.nextLine();
System.out.printf(" 輸入所屬部門
=>");
worker[k].depart = keyin.nextLine();
System.out.printf(" 輸入員工代號
=>");
worker[k].ID = keyin.nextInt();
System.out.printf(" 輸入員工底薪
=>");
worker[k].payment = keyin.nextInt();
System.out.printf(" 輸入薪資加級
=>");
worker[k].duty = keyin.nextInt();
keyin.nextLine();
System.out.printf(" 是否繼續輸入員工資料
(yes/no) =>");
sel = keyin.nextLine();
k = k+1;
}
System.out.printf(" *****
印出員工薪資表
*****\n");
System.out.printf("
員工資料 \t\t 薪資總額 \t 預扣稅額 \t 應領薪資 \n");
for (int i=0; i<k; i++) {
System.out.printf(" %s ", worker[i].name);
System.out.printf("(%d ", worker[i].ID);
System.out.printf("%s)\t",
worker[i].depart);
value = worker[i].payment+worker[i].duty;
System.out.printf(" %d\t\t", value);
tax = (int)(value * 0.1);
System.out.printf("%d\t\t", tax);
value = value - tax;
System.out.printf("%d\n", value);
}
}
}
( D ) 程式重點說明:
(1)
第 20
行 :『 int k=0; 』 。利用變數 k 紀錄目前資料的比數有多寡;宣告時給予初始值 0。
(2)
第 28~45
行 :『while(sel.equal(“yes”) && (k<20) ) { ….
sel = keyin.readLine(); k=k+1 ;}』。判斷如果輸入 yes 或 k 還小於 20,則繼續處理迴圈內敘述區塊。
(3)
第 30
行: 『worker[k] = new Employee() 』。產生一個 Employee 類別的物件,並填入 worker 陣列的第 k 個元素內。
(4)
第 32
行 :『 worker[k].name = keyin.readLine(); 』。讀入一行字串,並存入物件 worker[k] 的 name 變數成員內。
5-4-3 範例研討:超商販賣系統
VIDEO
( A )程式功能: Ex5_4.java
請幫『春嬌生鮮超市』建立一套販賣系統,電腦視窗能出現各項商品名稱與單價,操作者連續點選客人購買商品與數量,最後顯示出購買商品清單,並計算出購買金額。假設僅販賣:可口餅乾( 20 元)、味全鮮乳( 30 元)、御便當( 50 元)、黑松汽水( 20 元)、頻果西打( 30 元)與脆笛酥( 20 元),期望操作介面如下:
期望操作介面如下:
D:\Java2_book\chap5\Ex5_4>javac Ex5_4.java
D:\Java2_book\chap5\Ex5_4>dir/b
Element.class
Ex5_4.class
Ex5_4.java
D:\Java2_book\chap5\Ex5_4>java Ex5_4
****
歡迎光臨
春嬌超商
請選擇購買商品
****
(1)
可口餅乾
20
元
(2)
味全鮮乳
30
元
(3)
御便當
50
元
(4)
黑松汽水
20
元
(5)
頻果西打
30
元
(6)
脆迪酥
20
元
(7)
結算金額
請輸入選項
=>2
購買數量
=>5
****
歡迎光臨
春嬌超商
請選擇購買商品
****
(1)
可口餅乾
20
元
(2)
味全鮮乳
30
元
(3)
御便當
50
元
(4)
黑松汽水
20
元
(5)
頻果西打
30
元
(6)
脆迪酥
20
元
(7)
結算金額
請輸入選項
=>3
購買數量
=>2
****
歡迎光臨
春嬌超商
請選擇購買商品
****
(1)
可口餅乾
20
元
(2)
味全鮮乳
30
元
(3)
御便當
50
元
(4)
黑松汽水
20
元
(5)
頻果西打
30
元
(6)
脆迪酥
20
元
(7)
結算金額
請輸入選項
=>7
*****
購買清單如下
*****
品名
單價
數量
小計
味全鮮乳
30 5 150
御便當
50 2 100
總計
= 250
( B )製作技巧研討:
系統要求可連續選擇多項商品,再計算出總金額及印出購買清單,因此,必須準備一只物件陣列,存放客戶所購買產品名稱及數量。吾人規劃產品物件包含有:產品名稱、單價、數量、以及小計,其中小計表示該樣產品的金額。客戶選購產品時,則需產生陣列內的物件元素,再填入該產品的屬性,如圖 5-11 所示。
圖 5-16 Element 物件填入 cust 陣列中
另外,製作本系統重點提示如下:
(1) 系統操作時隨時由螢幕點選購買產品及數量,因此需將顯示產生清單編寫成一個獨立的函數,隨時呼叫執行( disp_Element())。
(2) 需要一個陣列物件隨時登錄客戶所購買產品及數量,並規劃該物件的類別內容( class Element{ …})。
(3) 利用 while 迴圈與 switch/case 判斷選擇店員的操作輸入,並假設客戶最多購買 20 樣產品。
( C )程式範例:
圖 5-17 Ex5_4 程式架構
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
96
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//Ex5_4.java
/*
請建立一套超商販賣系統,能顯示商品名稱與單價,
提供客人購買,最後印出結果
*/
import java.util.*;
class Element {
String name; //
商品名稱
int price; //
單價
int pice; //
購買數量
int sum; //
小計
}
public class Ex5_4 {
public static void main(String args[]) {
Scanner keyin = new Scanner(System.in);
Element[] cust = new Element[20]; //
登錄客戶購買產品
int select, k, no, total;
dispElement();
select = keyin.nextInt();
k=0;
while ((select != 7) && (k<20)) {
System.out.printf("\t 購買數量
=>");
no = keyin.nextInt();
switch (select) {
case 1:
cust[k] = new Element();
cust[k].name = " 可口餅乾 ";
cust[k].price = 20;
cust[k].pice = no;
k = k + 1;
break;
case 2:
cust[k] = new Element();
cust[k].name = " 味全鮮乳 ";
cust[k].price = 30;
cust[k].pice = no;
k = k + 1;
break;
case 3:
cust[k] = new Element();
cust[k].name = " 御便當 ";
cust[k].price = 50;
cust[k].pice = no;
k = k + 1;
break;
case 4:
cust[k] = new Element();
cust[k].name = " 黑松汽水 ";
cust[k].price = 20;
cust[k].pice = no;
k = k + 1;
break;
case 5:
cust[k] = new Element();
cust[k].name = " 頻果西打 ";
cust[k].price = 30;
cust[k].pice = no;
k = k + 1;
break;
case 6:
cust[k] = new Element();
cust[k].name = " 脆迪酥 ";
cust[k].price = 20;
cust[k].pice = no;
k = k + 1;
break;
default:
System.out.printf(" 請重新正確選擇
\n");
break;
}
dispElement();
select = keyin.nextInt();
}
/*
計算各產品小計與購買總金額
*/
total = 0;
for (int i=0; i<k; i++) {
cust[i].sum = cust[i].price * cust[i].pice;
total = total + cust[i].sum;
}
/*
列印購買清單
*/
System.out.printf("*****
購買清單如下
*****\n");
System.out.printf(" 品名 \t\t 單價
\t 數量 \t
小計 \n");
for (int i=0; i<k; i++)
System.out.printf("%s%10d%10d%10d\n",
cust[i].name,
cust[i].price, cust[i].pice,
cust[i].sum);
System.out.printf(" 總計
= %d\n", total);
}
/*
顯示客戶購買商品選項
*/
public static void dispElement(){
System.out.printf(" **
歡迎光臨
春嬌超商
請選擇購買商品
****\n");
System.out.printf("(1)
可口餅乾
20
元 \t");
System.out.printf("(2)
味全鮮乳
30
元 \t");
System.out.printf("(3)
御便當
50
元 \n");
System.out.printf("(4)
黑松汽水
20
元 \t");
System.out.printf("(5)
頻果西打
30
元 \t");
System.out.printf("(6)
脆迪酥
20
元 \n");
System.out.printf("(7)
結算金額 \n");
System.out.printf("\t 請輸入選項
=>");
}
}
( D )程式重點說明:
(1)
第 4~9
行 :『 class Element{ …} 』。 宣告物件陣列的原始類別。
(2)
第 15
行 :『 Element[] cust = new Element[20]; 』。產生準備登錄客戶謀買商品的物件陣列,假設最高可儲存 20 樣產品。
(3)
第 19
行 :『 k=0; 』。利用 k 變數紀錄客戶購買商品的筆數;其初始值為 0。
(4)
第 20~75
行 :『while(..) { switch(..) { ….}} 』。利用 while 迴圈與 switch/case 判斷選項,構成系統主要執行區域。
(5)
第 25
行 :『cust[k] = new Element(); 』。變數 k 是紀錄目前存放資料的筆數,又它是由 0 開始計算,因此 k 所指的是下一個資料的位置。此敘述功能是產生一個 Elment 物件後,存入陣列 cust 的第 k 位置( cust[k])。
5-4-4 自我挑戰:超商庫存管理系統 VIDEO
( A )程式功能: PM5_2.java
請您幫『春嬌生鮮超市』建立一套庫存管理系統,該系統功能有:盤點庫存量(顯示所有商品資料)、進貨登錄功能(點選商品編號、再輸入進貨量)、出貨登錄功能(點選商品編號,再輸入出貨量)。假設該超商僅有:可口餅乾(編號 A1001)、味全鮮乳(編號 A1002)、御便當(編號 A1003)、黑松汽水(編號 A1004)、頻果西打(編號 A1005)與脆笛酥(編號 A1006),功能如下:
(1) 期望操作介面有 5 個功能選項
D:\Java2_book\chap5\PM5_2>java PM5_2
**
歡迎光臨
春嬌超商
庫存管理系統
**
(1)
盤點庫存量
(2)
進貨登錄系統
(3)
出貨管理系統
(4)
離開系統
請輸入選項
=>
(2) 選擇進貨登錄系統 (選擇 2)操作如下:
**
歡迎光臨
春嬌超商
庫存管理系統
**
(1)
盤點庫存量
(2)
進貨登錄系統
(3)
出貨管理系統
(4)
離開系統
請輸入選項
=>2
(1) 可口餅乾 (A1001)
(2) 味全鮮乳 (A1002)
(3) 御便當
(A1003)
(4) 黑松汽水 (A1004)
(5) 頻果西打 (A1005)
(6) 脆迪蘇
(A1006)
請輸入選項
=>3
請輸入進貨數量
=>100
(3) 選擇盤點庫存量 (選擇 1)操作如下:
**
歡迎光臨
春嬌超商
庫存管理系統
**
(1)
盤點庫存量
(2)
進貨登錄系統
(3)
出貨管理系統
(4)
離開系統
請輸入選項
=>1
*****
盤點庫存量如下
*****
產品編號
產品名稱
庫存量
A1001 可口餅乾
300
A1002
味全鮮乳
30
A1003
御便當
100
A1004
頻果西打
50
A1005
頻果西打
20
A1006
脆迪酥
45
(4) 選擇出貨管理系統 (選擇 3與 1)操作如下:
**
歡迎光臨
春嬌超商
庫存管理系統
**
(1)
盤點庫存量
(2)
進貨登錄系統
(3)
出貨管理系統
(4)
離開系統
請輸入選項
=>3
(1) 可口餅乾 (A1001)
(2) 味全鮮乳 (A1002)
(3) 御便當
(A1003)
(4) 黑松汽水 (A1004)
(5) 頻果西打 (A1005)
(6) 脆迪蘇
(A1006)
請輸入選項
=>2
請輸入出貨數量
=>20
**
歡迎光臨
春嬌超商
庫存管理系統
**
(1)
盤點庫存量
(2)
進貨登錄系統
(3)
出貨管理系統
(4)
離開系統
請輸入選項
=>1
*****
盤點庫存量如下
*****
產品編號
產品名稱
庫存量
A1001
可口餅乾
300
A1002
味全鮮乳
10
A1003
御便當
100
A1004
頻果西打
50
A1005
頻果西打
20
A1006
脆迪酥
45
( B )製作技巧提示:
本系統較特殊的地方是,系統開始時需將所預定的 6 樣產品資料填入物件陣列中,吾人利用一個二維陣列( article[][])儲存這些資料,再寫一個簡單程式將他複製到物件陣列的產品名稱與編號上。其他程式規劃就較為簡單。
圖 5-18 PM5_2 程式架構
虛擬碼提示如下:
宣告描述商品的類別:
class Element {
String name; //
商品名稱
String ID; //
商品編號
int storage; //
庫存數量
int price; //
單價
}
宣告主類別範圍(
PM5_2 ): {
主方法( main() )範圍 {
宣告物件陣列( Element[]
cust = new Element[20] );
// 庫存陣列
宣告商品名稱與編號陣列:
String[][] article = {{" 可口餅乾 ",
"A1001"},
{" 味全鮮乳 ",
"A1002"},
{" 御便當
", "A1003"},
{" 頻果西打 ",
"A1004"},
{" 頻果西打 ",
"A1005"},
{" 脆笛酥
", "A1006"}};
將商品名稱與編號填入物件陣列中:
for (int i=0; i<6; i++) {
cust[i] = new Element();
cust[i].name = article[i][0];
cust[i].ID = article[i][1];
}
顯示並選擇輸入主工作目錄( mainMenu(),
select )
while ((select != 4)) {
switch (select) {
case 1:
顯示庫存量(顯示
cust[] 物件陣列內容);
case 2:
顯示商品選單及輸入( disp_Element(),
art );
讀取進貨數量( number );
累增至庫存量( cust[art-1].storage
=+ number );
case 3:
顯示商品選單及輸入( disp_Element(),
art );
讀取進貨數量( number );
扣除庫存量( cust[art-1].storage
=- number );
default:
顯示錯輸入;
}
顯示並選擇輸入主工作目錄( mainMenu(),
select )
}
}
顯示存管理系統工作選項函數( mainMenu() );
顯示庫存產品函數( disp_Element() );
}
程式片段如下:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
…….
class Element {
String name; //
商品名稱
String ID; //
商品編號
int storage; //
庫存數量
int price; //
單價
}
public class PM5_2 {
public static void main(String args[]) {
Scanner keyin = new Scanner(System.in);
Element[] cust = new Element[20]; //
庫存資料檔案
String[][] article = {{" 可口餅乾 ",
"A1001"},
{" 味全鮮乳 ",
"A1002"},
{" 御便當
", "A1003"},
{" 頻果西打 ",
"A1004"},
{" 頻果西打 ",
"A1005"},
{" 脆迪酥
", "A1006"}};
int select, art, number;
for (int i=0; i<6; i++) {
cust[i] = new Element();
cust[i].name = article[i][0];
cust[i].ID = article[i][1];
}
mainMenu();
select = keyin.nextInt();
while ((select != 4)) {
switch (select) {
case 1:
System.out.printf("*
盤點庫存量如下
**\n");
System.out.printf(" 產品編號 \t 產品名稱 \t 庫存量 \n");
for (int i=0; i<6; i++)
System.out.printf("%s\t\t%s\t%d\n", cust[i].ID,
cust[i].name,
cust[i].storage);
break;
case 2:
disp_Element();
art = keyin.nextInt();
System.out.printf(" 請輸入進貨數量
=>");
number = keyin.nextInt();
cust[art-1].storage =
cust[art-1].storage + number;
break;
case 3:
disp_Element();
art = keyin.nextInt();
System.out.printf(" 請輸入出貨數量
=>");
number = keyin.nextInt();
if(number > cust[art-1].storage)
System.out.printf(" 庫存不足 ,
拒絕出貨 \n");
else
cust[art-1].storage =
cust[art-1].storage - number;
break;
default:
System.out.printf(" 請重新正確選擇
\n");
break;
}
mainMenu();
select = keyin.nextInt();
}
}
/*
顯示庫存管理系統工作選項
*/
public static void mainMenu(){
…….
}
/*
顯示庫存產品
*/
public static void disp_Element() {
……
…..
}
}
翻轉工作室: 粘添壽
Java 程式設計(二) 含物件導向
翻轉電子書系列: