Ch03 物件導向程式設計_物件與類別

Download Report

Transcript Ch03 物件導向程式設計_物件與類別

Ch03 物件導向程式設計_物件與
類別
JAVA 程式設計入門(II)
2
本章大綱
•
•
•
•
•
•
物件導向程式設計介紹
類別與物件
屬性
方法
建構子
方法多載
4/9/2015
3
物件導向程式設計
• 「物件導向程式設計」是將真實世界中物件使用
上的優點,套用在程式設計上。
• 物件導向的一些優點:
▫ 使用者的角度
 封裝(Encapsulation):資訊隱藏,看不到內部運作,
內部也不受外界影響
 介面(Interface):人機溝通介面
 多型(Polymorphism):以不同的方式實作,作同樣的
功能
▫ 製造者的角度
 繼承(inheritance):使用舊有設計,再加添新功能
4
物件導向程式設計的優點
• 子物件之間以介面結合:透過介面,將數個物件結
合在一起,解決一個大問題
5
物件導向程式設計的優點
物件導向程式滸最重要的功能為程式碼的再利用,
使用封裝、繼承、介面與多型
更換子物件
6
物件導向程式設計的優點
• 使用多型(介面相同)
7
抽象化
設想物件「能做什麼」就是抽象化。
抽象化是設計「物件藍圖」的第一步,也是最重
要的一步。
物件內部如何運作而達到某個功能,並不是抽象
化的責任。
8
物件間訊息傳遞
• 程式中的物件是經過擬人化的。
• 物件有自己的名字,有自己的能力。
• 物件之間的訊息傳遞:
9
物件分類與類別
• 分類的功能:
▫ 每個分類都可成為資訊貯存的索引
▫ 分類可以歸納出「通則」
▫ 每個分類都有詮釋的功能
10
器具分類
器具的設計通常會延用某些舊的設計,
延用舊的部份即是「繼承」的概念。
11
• 根據藍圖(類別)可以生產許多產品(物件)
• 程式中的類別是物件設計藍圖,物件的功能全依類
別的定義來決定
• 類別就是自訂的資料型別
12
類別與物件
• 如果類別是設計圖, 物件就是利用設計圖實作出來
的東西
• 類別可想成是使用者定義的資料型態, 物件是以類
別宣告出來的變數
13
類別的定義
• 類別的定義語法
修飾字
{
class
類別名稱
//類別的標頭
// 屬性宣告
// 建構子定義
// 方法定義
}
▫ 三者順序沒有限制
▫ Java合法程式段落的最小單位為類別
▫ 之前的程式之類別定義只是當做起始方法main()的
包裹類別,沒有建立該類別的實體
14
類別的修飾字
• public-公開類別,宣告成此種類別可以被任何
類別所使用。
▫ 一個原始程式檔至多有一個public類別
▫ 一個檔案如果有多個類別時, 一個為public, 其他不可再
為public
• 無修飾字(default)類別,此種類別僅能被同一
套件(package)內的類別使用。
• final-此種類別不可被繼承。
• abstract-此為抽象類別的修飾字。此種類別至
少擁有一個抽象方法,不可用於直接建立物件。
15
類別的命名規則(非硬性規定)
• 類別名稱的第一個字母應該大寫,如:Car、
Person。
• 若是由兩個字以上組成時,每個單字的第一個字
母為大寫,如:CarClass。
• 名稱中包括縮寫時,所有縮寫字母為大寫,如:
URL。
class EmptyClass
{
}
16
建立物件
• 宣告物件
類別名稱
物件名稱;
• 建立物件實體
物件名稱 = new 類別名稱();
• 宣告並建立物件實體
類別名稱 物件名稱 = new 類別名稱();
•
•
•
•
物件名稱必須是合法的識別字。
其命名規則為第一個字的字母皆為小寫。
若為複合字時,其餘字的第一個字母為大寫。
若為縮寫字母時,皆為小寫。
17
範例1:EX7_1.java宣告及初始化兩個物件
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class EX7_1
{
public static void main(String [] args)
{
EmptyClass emptyClass = new EmptyClass();
EX7_1 ex7_1 = new EX7_1();
System.out.println(emptyClass);
System.out.println(ex7_1);
}
}
//空類別定義
class EmptyClass
{
}
18
範例1:EX7_1.java結果
19
屬性(attribute)
• 屬性就是變數,屬性變數,欄位變數
• 屬性要在類別內,方法外或建構子外宣告
• 屬性的宣告語法
修飾字 資料型態
屬性名稱;
• 存取權限相關的修飾字
▫ public-公用級,所有類別皆可使用此級屬性。
▫ protected-保護級,同一套件內及其子類別可以直接
使用。
▫ 無修飾字-預設級(default)或稱套件級,同一套件內
的類別可以直接使用。
▫ private-私有級,屬性所在的類別才能使用。
20
範例2:EX7_2.java屬性存取修飾字的權限
1.
class EX7_2
2.
{
3.
public static void main(String [] args)
4.
{
5.
AccessTest at = new AccessTest();
6.
System.out.println(at.pub);
7.
System.out.println(at.pro);
8.
System.out.println(at.def);
//System.out.println(at.pri); //不可使用物件的
private屬性
9.
System.out.println(at.att);
10.
System.out.println(at.arr);
11.
System.out.println(at.ex7_2);
12.
}
13. }
1.
2.
3.
4.
5.
6.
7.
class AccessTest
{
public int pub = 1;
protected int pro = 2;
int def =3;
private int pri =4;
boolean att;
//未初始化的變數
8.
int[] arr;
9.
EX7_2 ex7_2;
10. }
21
屬性
• 使用final修飾字自訂常數(設定成不能變更的常
數),宣告時同時設定其值
public final int wheels = 4;
• static修飾者為類別屬性, 類別屬性是同一類別中
所有物件所共有,而不專屬於某個物件
• 取用物件的屬性: 使用點(dot)運算子指出取用
的屬性
物件名稱.屬性名稱
• 屬性只要宣告就會自動初始化,設上預設值
整數:0
布林值: false
浮點數: 0.0f或0.0d
參照變數: null
22
範例3:EX7_3.java物件屬性與類別屬性
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
class EX7_3
{
int i = 0;
static int s = 100;
public static void main(String [] args)
{
EX7_3 obj1 = new EX7_3();
EX7_3 obj2 = new EX7_3();
System.out.println(++obj1.i);
System.out.println(++obj1.s);
System.out.println(obj2.i += 10);
System.out.println(obj2.s += 10);
System.out.println("obj1.s=\t" + obj1.s);
System.out.println("obj2.s=\t" + obj2.s);
System.out.println("EX7_3.s=" + EX7_3.s);
System.out.println("s=\t" + s);
}
}
範例3:EX7_3.java物件屬性與類別屬性
• 類別成員和物件成員的區別
class EX7_3
s
s
i
main()
obj1
obj2
s
i
23
範例4:EX7_4.java指向同類別的參照變數
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
class EX7_4
{
int i;
EX7_4 ex;
public static void main(String [] args)
{
EX7_4 obj = new EX7_4();
obj.ex = new EX7_4();
obj.ex.i = 1;
obj.ex.ex = new EX7_4();
obj.ex.ex.i = 2;
System.out.println(obj.i);
System.out.println(obj.ex.i);
System.out.println(obj.ex.ex.i);
}
}
24
範例4:EX7_4.java指向同類別的參照變數
• 物件的鏈結
EX7_4 obj = new EX7_4();
obj
i = 0
ex = null
obj.ex = new EX7_4();
obj.ex.i = 1;
obj
obj.ex.ex = new EX7_4();
obj.ex.ex.i = 2;
obj
i = 0
i = 1
ex
ex = null
i = 0
i = 1
i = 2
ex
ex
ex = null
25
26
方法
• 定義方法
<修飾字> 資料型別 方法名稱(<形式參數列>)
{
// 方法中的敘述
<return 回傳值;>
}
▫ 修飾字、形式參數列和return敘述為非必要。
▫ 資料型別和方法名稱為必要。
▫ 方法的資料型別必須和回傳值相同。資料型別void表示
不回傳任何值
▫ 形式參數列用以接受傳入值的變數,變數型別也要在參
數列中確實宣告
27
方法
• 方法的命名規則
▫ 一般方法名稱的前面部份會是一個動詞,動詞應全
為小寫。
▫ 動詞後的字,第一個字母為大寫。
▫ 若方法是為了設定或取得private屬性,則分別使用
「set屬性名稱」和「get屬性名稱」。
28
方法
• 形式參數式中,以逗號分隔各個形式參數
public int getArea(int w, int h)
{
return w*h;
}
• static修飾方法時,該方法為類別方法
• 抽象方法沒有實作,無方法主體
abstract <修飾字> 資料型別 方法名稱(<形式參數列>);
29
方法的呼叫
• 呼叫方法的語法
物件名稱.方法名稱(<參數列>)
▫ 參數列的工作是把參數傳給方法。
▫ 參數列為選擇性的功能,視方法定義的形式參數列
而定。
方法的呼叫
• 呼叫方法時的程式走向
public static void main(String [] args)
{
System.out.println("We love");
listTree();
System.out.println("and");
listTree();
System.out.println("love us!");
}
static void listTree()
{
...
}
30
範例5:EX7_5.java呼叫方法
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
class EX7_5
{
public static void main(String [] args)
{
System.out.println("We love");
listTree();
System.out.println("and");
listTree();
System.out.println("love us!");
}
//listTree方法定義
static void listTree()
{
System.out.println(" * ");
System.out.println(" *** ");
System.out.println(" ***** ");
System.out.println("*******");
System.out.println(" *** ");
}
}
31
範例1:EX7_5.java呼叫類別方法
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
class EX7_5
{
public static void main(String [] args)
{
System.out.println("We love");
listTree(); //呼叫類別方法
System.out.println("and");
listTree();
System.out.println("love us!");
}
//listTree方法定義,此方法為類別方法
static void listTree()
{
System.out.println(" * ");
System.out.println(" *** ");
System.out.println(" ***** ");
System.out.println("*******");
System.out.println(" *** ");
}
}
32
33
方法的型別與回饋值
• 傳值和傳參照
▫ 基本型別(boolean、byte、short、int、long、
char、float及double)是以傳值的方式回傳。
▫ 自訂型別(陣列或物件)是以傳參照的方式回傳資
料。
範例2:EX7_6.java呼叫物件方法
1. class EX7_6
2. {
3.
public static void main(String [] args)
4.
{
5.
int a = 2;
6.
byte b = 6;
7.
double c = 5.0;
8.
EX7_6 obj = new EX7_6(); //建立物件
9.
obj.listStar(a);
//呼叫物件的方法
10.
obj.listStar(b);
11.
obj.listStar( (int)c );
12. }
13.
14.
15.
16.
17.
18.
19.
20.
21.
//listStar方法定義
void listStar(int n)
{
while(n-->0)
System.out.print("*");
System.out.print("\n");
}
}
34
範例2:EX7_6.java方法的呼叫
• 參數只傳遞數值
2
public static void main(String [] args)
{
int a = 2;
byte b = 6;
double c = 5.0;
EX7_6 obj = new EX7_6();
void listStar(int n)
{
while(n-->0)
System.out.print("*");
System.out.print("\n");
}
2
obj.listStar(a);
obj.listStar(b);
obj.listStar( (int)c );
}
35
36
傳參照呼叫
• 陣列名稱和物件名稱為參照變數
• 當方法的參數是基本資料型別時, 為傳值
• 當參數是陣列或物件時, 是以參照傳入,而參照即
為實體的位址
• 當方法取得的是參照時, 操作的是照所指向的陣列
實體, 因此, 實體內容會被改變
37
範例3:EX7_7.java參照變數的傳遞
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
class EX7_7
{
//程式起始方法
public static void main(String [] args)
{
int[] arr = {9, 4, 5, 1, 6, 8};
System.out.println("main內arr的參照: "+arr);
showArr(arr); //呼叫顯示陣列內容的方法
sortArr(arr); //呼叫排序方法
showArr(arr); //呼叫顯示陣列內容的方法
}
//顯示陣列內容
static void showArr(int[] a)
{
for(int i=0; i<a.length; i++)
System.out.print(a[i]+"\t");
System.out.print("\n");
}
38
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
•
•
//選擇排序
static void sortArr(int[] a)
{
System.out.println("sortArr內a的參照: "+a);
for(int i=0; i<a.length-1; i++)
for(int j=i+1; j<a.length; j++)
if(a[i] > a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
陣列arr和a是指向同一個實體陣列,所以對arr或a陣列作任何更動時,
皆對同一個陣列作用
Return之後只能接一個運算式或變數,也就是一個變數,如果要傳遞
兩個變數以上,只要將多個變數放在陣列或物件中即可
範例4:EX7_8.java求最大因數
39
1. class EX7_8
1. //求最大的因數
2. {
2. static int maxFactor(int n)
3.
public static void main(String [] args)
3. {
4.
{
4.
for(int i=n-1; i>1; i--)
5.
int num, factor;
5.
if(n%i == 0)
6.
if(args.length<1)
6.
return i; //回傳找到的因數
7.
{
7.
return 0; //找不到小於本身的因數
8.
System.out.println("請傳入一大於零的整數!");
8. }
9.
return;
//返回
10.
}
11.
num = Integer.parseInt(args[0]); //將程式參數轉換成整數
12.
if(num < 2)
13.
{
14.
System.out.println("整數必須大於1!");
15.
return;
//返回
16.
}
17.
factor = maxFactor(num);
18.
if(factor==0)
19.
System.out.println(num+"為質數!");
20.
else
21.
System.out.println(num+"的最大因數為"+factor);
22.
}
40
範例5:EX7_10.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
class EX7_10
{
public static void main(String [] args)
{
int[] ori = {5, 2, 0, 7, 8, 9};
int[] dup;
dup = duplicateArray(ori);
System.out.println("ori: " + ori);
showArr(ori);
System.out.println("dup: " + dup);
showArr(dup);
}
//複製陣列
static int[] duplicateArray(int[] a)
{
int[] b = new int[a.length];
for(int i=0; i<a.length; i++)
b[i] = a[i];
return b;
//回傳陣列參照
}
1.
2.
3.
4.
5.
6.
7.
8.
//顯示陣列內的元素值
static void showArr(int[] a)
{
for(int i=0; i<a.length; i++)
System.out.print(a[i]+"\t");
System.out.print("\n");
}
}
41
變數的有效範圍
• 大括弧{ }是變數領域的藩籬
▫ 若一個變數於某個區塊內宣告,則區塊內從宣告點以下
為變數的領域。
▫ 區塊外不為變數的領域。
{
int j=1;
}
j++;
//錯誤,無法識別變數j
42
變數的有效範圍
static void methodName(int a)
{
int b = 2;
System.out.println("a:"+a);
System.out.println("b:"+b);
for(int c = 0; c<10; c++)
{
if(c==3)
System.out.println("c:"+c);
}
c
a
b
int d = 4;
的
的
領
if(d==4)
{
System.out.println("d:"+d);
int e = 5;
System.out.println("e:"+e);
}
領
域
域
d
e
領
域
{
int f = 6;
System.out.println("f:"+f);
}
}
的
f
43
範例1:EX7_11.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
static void methodName(int a)
{
int b = 2;
System.out.println("a:"+a);
System.out.println("b:"+b);
for(int c=0; c<10; c++)
{
if(c==3)
System.out.println("c:"+c);
}
int c = 4; //此C非前面的C
if(c==4)
{
System.out.println("c:"+c);
int e=5;
System.out.println("e:"+e);
}
{
int f=6;
System.out.println("f:"+f);
}
}
44
變數的有效範圍
• 屬性也稱為欄位變數。
• 方法內的變數稱為自動變數或區域變數。
• 自動變數和欄位變數同名是合法的情況,不過
兩者若同名,則欄位變數會因為被遮蔽而無法
在方法內被「看到」。
• 欲在方法內看到同名的屬性時,可以使用this
關鍵字,指出使用的是物件本身的屬性。
this.屬性名稱
• This表示物件的參照,可以用來指出物件屬性
或類別屬性;但是,this不能在類別方法內使用,
因為類別方法位於類別之內,沒有所屬的物件
45
範例2:EX7_12.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
int a =10;
//屬性
int b = 20; //屬性
public static void main(String [] args)
{ EX7_12 obj = new EX7_12();
obj.myMethod(1);
}
//myMethod方法
void myMethod(int a)
{ System.out.println("方法內 a:" + a);
System.out.println("方法內 this.a:" + this.a);
{
{
int b=2;
System.out.println("巢狀區塊內 b:" + b);
System.out.println("巢狀區塊內 this.b:" + this.b);
}
System.out.println("區塊內 b:" + b);
System.out.println("區塊內 this.b:" + this.b);
}
}
46
變數的有效範圍
class EX7_12
{
int a =10;
屬性a的領域
屬性b的領域
public static void main(String [] args)
{
EX7_12 obj = new EX7_12();
obj.myMethod(1);
}
void myMethod(int a)
{
...
自動變數a的領域
{
{
int b=2;
...
}
...
}
}
int b = 20;
}
自動變數b的領域
47
方法多載
• 同一類別中,若定義數個相同名稱的方法,而各
方法所需的參數不同時,稱為方法多載
(Overloading)。
• 多載方法是以傳入的參數個數及參數型別做為呼
叫的判斷依據。
• 多載方法的形式參數的個數及型別相同時,為非
法定義。
• 多載的目的是因應不同的傳遞資料,讓方法更有
彈性。
48
範例7:EX7_17.java測試多載子
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public static void main(String [] args)
{
testVar( 9, 6 );
testVar( 7 );
testVar( (byte)6 );
testVar( 2.5 );
testVar( '中' );
}
static void testVar(byte n)
{
System.out.println("傳入一個byte型別參數");
}
static void testVar(int n)
{
System.out.println("傳入一個int型別參數");
}
// 取消下段的標註符號將出現錯誤: testVar(int) is already defined
/* static int testVar(int n)
{
System.out.println("傳入一個int型別參數");
return n;
} */
49
範例7:EX7_17.java測試多載子
1.
2.
3.
4.
5.
6.
7.
8.
static double testVar(double n)
{
System.out.println("傳入一個double型別參數");
return n;
}
static void testVar(int n, int m)
{
System.out.println("傳入兩個int型別參數");
}
50
建構子(constructor)
• 何謂建構子:以一個方法來設定物件屬性的初值,
可視建構子為一個特殊的方法
• 建構子的目的:當產生一個物件的同時,同時將
屬性初值進行設定
51
建構子
使用new及建構子建立物件
物件名稱 = new 類別名稱();
呼叫建構子
52
範例1:建構子
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
class ConstructorDemo
{ public static void main(String args[])
{ Student Peter=new Student();
System.out.println(" Peter的資料-->使用Student()建構式") ;
Peter.getShow() ;
Student David=new Student(1000) ;
System.out.println(" David的資料-->使用Student(1000)建構式") ;
David.getShow() ;
Student Mary =new Student(48, 150) ;
System.out.println(" Mary的資料 -->使用Student(48, 150)建構式") ;
Mary.getShow() ;
}
}
53
範例1:建構子
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class Student
{ private int height, weight ;
Student()
{
weight=4 ;
height=50 ;
}
Student(int w)
//Student類別的建構式,須設定一個引數
{
setWeight(w) ; //呼叫setWeight方法初始化weight資料成員
height=50 ;
//初始化height資料成員的值為50
}
Student(int w, int h)
//Student類別的建構式,須設定兩個引數
{
setWeight(w) ;
setHeight(h) ;
}
54
範例1:建構子
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
void setWeight(int w)
{
if (w>=40 && w<=150)
weight=w ;
else
weight=40;
}
void setHeight(int h)
{
if (h>=50 && h<=250)
height=h ;
else
height=50;
}
void getShow()
{
System.out.println(" 身高是: "+height);
System.out.println(" 體重是: "+weight + "\n");
}
}
55
預設的建構子
• 沒有定義建構子的類別時,編譯器會自動設給一
個沒有形式參數的建構子(預設建構子)。
• 預設的建構子是沒有內容的,不會對物件的屬性
有任何影影響。
• Constructor的名稱必須和類別擁有相同的名稱才
可以
• Constructor沒有傳回型態,即使void也不需要
• Constructor也可以多載,其做法和方法多載一樣,
是使用不同的引數串列的個數和引數串列的資料
型別來加以區隔constructor
56
預設的建構子
• 如果在定義類別時,若有定義至少一個建構子,
則編譯器不會設給任何預設建構子。
▫ 此時,程式設計者必須自己定義,如範例1中的
Student()。如果範例1中的屬性(height, weight)在
宣告時也給了初始值(或Java在宣告後自動設定初
始值為0),則建構子Student()內是空的
57
定義建構子
• 建構子的名稱一律同類別名稱,而且不宣告回傳
資料型別。
修飾字
{
類別名稱(形式參數列)
//程式敘述
}
• 建構子的修飾字可以為public、protected、
private或無修飾字。
• 建構子修飾字不使用static和abstract。
58
定義建構子
• 建構子也可以多載
class SomeClass
{
public SomeClass()
{
//不使用參數建立物件
}
public SomeClass(int x, int y)
{
//使用參數建立物件
}
}
59
建構子的呼叫
• 建立物件時呼叫建構子
類別名稱
物件名稱 = new 類別名稱(形式參數列);
• 方法可以和建構子同名。有回傳型別者為方法;
反之,無回傳型別者為建構子。
60
範例2:EX7_19.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class EX7_19 //程式起始方法
{ public static void main(String [] args)
{
Rectangle rect1 = new Rectangle();
//以沒有參數的建構子建立物件
System.out.println("rect1的面積為:" + rect1.getArea());
Rectangle rect2 = new Rectangle(3, 4); //以需要兩個參數的建構子建立物件
System.out.println("rect2的面積為:" + rect2.getArea());
}}
class Rectangle //Rectangle類別定義
{ int height; //高
int width; //寬
public Rectangle() //沒有參數的建構子
{
height = 1;
width = 1;}
public Rectangle(int height, int width) //需要兩個參數的建構子
{
this.height = height; //區域變數會遮敝屬性
this.width = width; }
public int getArea() //求得面積的方法
{
return height*width; }}
61
範例2:EX7_19.java延伸
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class EX7_19 //程式起始方法
{ public static void main(String [] args)
{
Rectangle rect1 = new Rectangle();
//以沒有參數的建構子建立物件
System.out.println("rect1的面積為:" + rect1.getArea());
Rectangle rect2 = new Rectangle(3, 4); //以需要兩個參數的建構子建立物件
System.out.println("rect2的面積為:" + rect2.getArea());
}}
class Rectangle //Rectangle類別定義
{ int height; //高
int width; //寬
public Rectangle() //沒有參數的建構子
{
height = 1;
width = 1;}
public Rectangle(int height, int width) //需要兩個參數的建構子
{
height = height;
//區域變數會遮敝屬性
width = width;
}
結果??
public int getArea() //求得面積的方法
{
return height*width; }}
62
範例2:EX7_19.java延伸(結果)
63
使用this()
建構子多載時,建構子可以呼叫其它建構子,不
過有以下限制:
▫ 必須使用 this() 取代類別名稱()。
▫ 只能在第一個敘述呼叫。
▫ 不能造成建構子遞迴。
64
封裝
• 封裝的特點:
▫ 隱藏類別實作的細節。
▫ 強迫使用者透過方法來操作屬性,如此可以保護資
料不會被濫用。
▫ 使程式碼更容易被維護。
65
封裝
• 沒有封裝的
物件:兩個使用者
可以同時要求設定
屬性一
• 完整封裝
的物件:使用者必
須透過方法來設定
屬性一時,此時二
人必須排隊來使用
方法
甲
使
用
者
乙
屬性一
物件
使
用
者
屬性二
乙
甲
使
用
者
使
用
者
方法一
物件
方法二
66
完整封裝的物件
• 屬性宣告為private
• 會設定一些方法來取用屬性,而這些方法為
public
• 但有些方法還是宣告為private,這些方法也不能
被其他型別的物件呼叫
67
範例5:EX7_22.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class EX7_22
{
//程式起始方法
public static void main(String [] args)
{
銀行帳號 哈利 = new 銀行帳號("8888", 100);
哈利.存款(2000);
哈利.提款("6666", 10000);
哈利.提款("8888", 10000);
哈利.查詢("8888");
哈利.提款("8888", 1000);
//System.out.println(哈利.金額); //錯誤
//哈利.查詢();
}
}
//錯誤
68
範例5:EX7_22.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
class 銀行帳號
{ private String 密碼;
private int 金額;
銀行帳號(String 密碼, int 開戶金)
{
this.密碼 = 密碼;
金額 = 開戶金;
System.out.print("恭喜開戶成功! ");
查詢();
//呼叫查詢方法
public void 存款(int 存入金)
{
金額 += 存入金;
System.out.print("完成存入! ");
查詢();
//呼叫查詢方法
}
}
69
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public void 提款(String 密碼, int 提出金)
{ if( this.密碼.equals(密碼) )
{
if(提出金 <= 金額)
{ 金額 -= 提出金;
System.out.print("完成提出:"+ 提出金 +" ");
查詢();
//呼叫查詢方法
}
else
System.out.println("剩餘金額不夠提出:"+提出金);
}
else
System.out.println("密碼錯誤!");
}
private void 查詢()
{ System.out.println("目前金額:" + 金額);
}
public void 查詢(String 密碼)
{ if( this.密碼.equals(密碼) )
查詢();
//呼叫查詢方法
else
System.out.println("密碼錯誤!");
}
70
大富翁.java
1.
class 大富翁
2.
{
3.
public static void main(String [] args)
4.
5.
{
玩家 [] A = new 玩家[4];
6.
A[0] = new 玩家();
7.
A[1] = new 玩家();
8.
A[2] = new 玩家();
9.
A[3] = new 玩家();
10.
A[0].名字 = "趙一";
11.
A[1].名字 = "王二";
12.
A[2].名字 = "張三";
13.
A[3].名字 = "李四";
14.
for(int i = 0; i < 20; i++)
15.
16.
{
System.out.println("第" + i + "輪:");
17.
for(int j = 0; j < 4; j++)
18.
19.
{
A[j].位置 = A[j].位置 + 骰子.擲骰子();
20.
if (A[j].位置 >= 40)
21.
A[j].位置 = A[j].位置 - 40;
22.
System.out.println(A[j].名字 + "的位置在" + A[j].位置);
23.
}
24.
25.
26. }
}
}
4/9/2015
27.
28.
29.
30.
31.
32.
33.
class 骰子
{
static int 擲骰子()
{
return (int)(Math.random()*11+2);
}
}
34.
35.
36.
37.
38.
39.
class 玩家
{
String 名字;
int 錢 = 10000;
int 位置 = 0;
}