Download presentation
Presentation is loading. Please wait.
1
第6章 類別與物件 – 封裝 6-1 物件導向的基礎 6-2 Java的類別與物件 – 封裝 6-3 類別的建構子
6-4 使用物件的成員資料 6-5 在物件使用類別變數與方法
2
6-1 物件導向的基礎 6-1-1 物件是第二個黑盒子 6-1-2 物件導向分析與設計 6-1-3 物件導向程式語言
6-1-4 UML的基礎
3
6-1 物件導向的基礎 「物件導向程式設計」(Object-oriented Programming,OOP)是第4章模組化程式設計的一種重要的轉變,一種更符合人性化的程式設計方法,因為我們本來就生活在一個物件的世界,思考模式也導循著物件導向模式。
4
6-1-1 物件是第二個黑盒子-說明 「物件」(Object)是物件導向技術的關鍵,以程式的角度來說,物件是資料與相關程序和函數結合在一起的組合體,資料是變數,程序和函數在Java語言稱為方法,如下圖所示:
5
6-1-1 物件是第二個黑盒子-封裝 物件的方法是對外的使用介面,變數和方法都包裹在一個黑盒子,實作程式碼都包裹隱藏起來,稱為「封裝」(Encapsulation)。 對於程式設計者來說,我們並不用考慮黑盒子內部的程式碼是如何撰寫,只需要知道這個物件提供什麼介面和如何使用它。 事實上,開車時並不需要了解車子為什會發動,換擋的變速箱擁有多少個齒輪才能正確操作,車子對我們來說只是一個黑盒子,唯一要作的是學習如何開好車。同理,沒有什麼人了解電視如何能夠收到訊號,但是我們知道打開電源,更換頻道就可以看到影像。
6
6-1-1 物件是第二個黑盒子-特性 狀態(State):物件所有「屬性」(Attributes)目前的狀態值,屬性是用來儲存物件的狀態,可以簡單的只是一個布林值變數,也可能是另一個物件,例如:車子的車型、排氣量、色彩和自排或手排等屬性。 行為(Behavior):行為是物件可見部分提供的服務,可以作什麼事,例如:車子可以發動、停車、加速和換擋等。 識別字(Identity):識別字是用來識別不同的物件,每一個物件都擁有獨一無二的識別字,Java語言是使用物件參考(Reference)作為物件的識別字,簡單的說,就是物件實際儲存的記憶體位址。
7
6-1-2 物件導向分析與設計-由上而下分析法的問題
在1970~80年間主要的軟體工程程式分析方法是第4章說明的「由上而下分析法」(Top-down Design),不過這種分析方法有一些問題,如下所示: 由上而下分析法的整個處理過程,只是找出解決問題的程序或函數,也就是各別程序或函數的程式碼,而沒有真正的考量到程式使用的資料本身。 由上而下分析法得到的程序或函數很難被重複使用,因為這些程序或函數都是針對特定問題所量身定製,程序或函數需要大幅修改才能使用在其他問題上。
8
6-1-2 物件導向分析與設計-解決方式 為了解決上述問題,由上而下的分析法經常需要配合「由下而上分析法」(Bottom-up Design),這種方法是由下而上,先尋找可以重複使用的軟體元件,然後由下而上組合起來,以解決整個問題,如下圖所示:
9
6-1-2 物件導向分析與設計-資訊隱藏 重複使用的軟體元件就是物件,它如同電腦硬體的「隨插即用」(Plug and Play),只需將它插入軟體系統就可以馬上運作,而不用考慮物件本身的詳細內容,只需符合系統需求,可以把實際處理的資料隱藏起來,稱為「資訊隱藏」(Information Hiding)。 在1980年代初期的物件導向程式設計(Object-oriented Programming)是將原來專注於演算法的程序和函數分解,轉換成了解問題本質的物件,將整個軟體視為一個定義完善的物件集合,整個程式是由這些物件所組成,強調物件的重複使用,在建立好下一層的每一個物件後,由下而上組合成一個完善的物件集合,以解決整個問題。
10
6-1-3 物件導向程式語言-種類 物件導向程式語言的精神是物件,不過支援物件的程式語言並不見得是一種物件導向程式語言,它可能只是一種物件基礎程式語言,如下所示: 物件基礎程式語言(Object-based Languages):只提供資料抽象化和物件觀念,例如:VB 6,不過,新版VB.NET、Visual Basic 2005/2008是物件導向程式語言。 物件導向程式語言(Object-oriented Languages):支援封裝、繼承和多形的觀念。
11
6-1-3 物件導向程式語言-封裝 封裝(Encapsulation)是將資料和處理資料的程序與函數組合起來建立物件。在Java語言定義物件是使用「類別」(Class),內含屬性和方法,屬於一種抽象資料型態(Abstract Data Type),換句話說,就是替程式語言定義新的資料型態。
12
6-1-3 物件導向程式語言-繼承 繼承(Inheritance)是物件的再利用,當定義好一個類別後,其他類別可以繼承這個類別的資料和方法,並且新增或取代繼承物件的資料和方法。
13
6-1-3 物件導向程式語言-多形 多形(Polymorphism)屬於物件導向最複雜的特性,類別如果需要處理各種不同資料型態時,並不需要針對不同資料型態來建立不同的類別,可以直接繼承基礎類別,繼承此類別建立同名方法處理不同的資料型態,因為方法的名稱相同,只是程式碼不同,所以也稱為「同名異式」。
14
6-1-4 UML的基礎-源由 UML(Unified Modelling Language)中文稱為塑模語言,UML的出現是三位OO理論大師:Grady Booch、James Rumbaugh和Ivar Jacobson(通稱3 Amigo)所提倡。 UML草案版本0.8版在1995年10月提出,1995年底Ivar Jacobson也加入Rational公司後,再整合他的OOSE(Object-Oriented Software Engineering)方法論,1997年1月UML正式產生,目前UML已經是OMG(Object Management Group)組織的標準。
15
6-1-4 UML的基礎-說明 UML統一三人表示方法的符號,並不是三位提出的方法論,換句話說,如同繪製電子元件、工程機械圖的標準符號,UML是程式語言的標準符號,以便程式分析者和程式設計者擁有溝通的語言。 在本書是使用UML的類別圖來表示Java語言的類別宣告和架構。
16
6-2 Java的類別與物件 – 封裝 6-2-1 類別與物件 6-2-2 成員資料的存取 - 資訊隱藏
6-2-3 物件的使用介面 - 成員方法
17
6-2 Java的類別與物件 – 封裝 Java的類別是用來建立物件,更正確的說是沒有宣告成static的部分,才是屬於物件原型。它是一種使用者自行定義的資料型態。 Java物件使用變數儲存狀態稱為「屬性」(Property)或「實例變數」(Instance Variables,也稱為副本變數),各種行為的程序和函數,在Java稱為方法(Methods)。
18
6-2-1 類別與物件-說明 Java類別宣告是物件的原型宣告,對於物件原型宣告的類別可以分為2個部分,如下所示:
成員資料(Data Member):物件的資料部分,屬於基本資料型態的變數、常數或其它的物件的「成員變數」(Member Variables)。 成員方法(Method Member):物件的操作部分,即程式與函數,也就是Java的方法。
19
6-2-1 類別與物件-宣告類別 Java類別宣告語法,如下所示: class 類別名稱 { 存取敘述修飾子 資料型態 成員資料; ……….
存取敘述修飾子 傳回值型態 成員方法( 參數列 ) 程式敘述; } ……
20
6-2-1 類別與物件-類別與物件(說明) 在Java程式是使用類別原型建立物件,稱此物件屬於類別的「實例」(Instance)或稱為副本,物件的變數稱為「實例變數」(Instance Variables),物件的程式或函數稱為「實例方法」(Instance Methods)。 同一個類別可以當作範本建立無數個物件實例,每一個物件都屬於類別的實例,或直接稱為物件。
21
6-2-1 類別與物件-類別與物件(圖例)
22
6-2-1 類別與物件-範例 例如:Time類別宣告,如下所示: class Time { public int second;
public int minute; public int hour; public void printTime() { System.out.println(hour+":"+ minute+":"+second); }
23
6-2-1 類別與物件-宣告物件變數 (說明) 在宣告Java類別後,我們就可以建立物件,首先將類別當作一種新的資料型態,使用新資料型態宣告所需的物件變數,如下所示: Time now, open, close; 上述程式碼宣告Time類別的變數now、open和close,稱為物件變數,變數內容是參考的指標,這個指標就是物件的識別字(Identity),目前我們只有宣告物件變數,並沒有真正建立物件。
24
6-2-1 類別與物件-宣告物件變數 (圖例) Java物件變數的內容並不是物件本身,物件變數是儲存物件「參考」(Reference)的指標,所謂建立物件是配置一塊記憶體空間儲存物件的內容(實例變數和方法),類別宣告的物件變數儲存的是這塊記憶體空間的位址,告訴我們如何找到此物件,如下圖所示:
25
6-2-1 類別與物件-建立物件實例 在Java建立物件需要使用new運算子,這個運算子可以依照類別的範本來建立物件,傳回指向此物件的參考指標,此過程稱為「實體化」(Instantiation),將類別實體化成物件實例,如下所示: close = new Time(); 上述指令使用new運算子建立Time類別的物件實例,物件變數close的值並不是物件本身,而是參考到此物件的指標。
26
6-2-1 類別與物件-存取實例變數與方法(說明)
在建立好物件後,就可以存取物件的實例變數與方法,其語法如下所示: 物件.實例變數 物件.實例方法 上述物件的實例變數和方法都是使用”.”運算子,而且只能存取宣告成public修飾子的變數和方法。
27
6-2-1 類別與物件-存取實例變數與方法(範例)
以Time類別建立的物件為例,如下所示: close.hour = 22; close.minute = 30; close.second = 30; 上述指定敘述指定物件變數close參考物件的實例變數hour、minute和second的值。同樣的語法可以呼叫實例方法,如下所示: close.printTime();
28
6-2-1 類別與物件-存取實例變數與方法(圖例)
類別可以建立多個物件實例,每一個物件都可以呼叫自己的實例方法或存取實例變數,而所謂執行方法就是送出不同的訊息,如下所示: now.printTime(); open.printTime(); close.printTime();
29
6-2-1 類別與物件-Ch6_2_1.java 在執行Ch6_2_1.java的Java程式後,電腦記憶體空間的內容,如下圖所示:
30
6-2-2 成員資料的存取 - 資訊隱藏 (說明) Java類別宣告的成員資料或方法可以使用private和public兩種修飾子來指定其存取方式,其說明如下所示: private修飾子:成員資料或成員方法只能在類別本身呼叫或存取。 public修飾子:成員資料或方法是此類別建立物件對外的使用介面,可以讓其他類別的程式碼呼叫此物件的實例方法或存取實例變數。
31
6-2-2 成員資料的存取 - 資訊隱藏 (範例) 例如:將Time類別的成員資料都宣告成private,然後透過宣告成public的成員方法setTime()和printTime()來進行存取,如下所示: class Time { private int second; private int minute; private int hour; public boolean setTime(int h, int m, int s) { } public void printTime() { } }
32
6-2-3 物件的使用介面 - 成員方法 (說明) 在Java類別的成員方法如果宣告成public,表示這些方法是物件的使用介面,但是有一些方法,例如:第6-2-2節程式範例的validateTime()方法因為只有類別本身在呼叫,我們只需宣告成private讓類別本身使用即可,這種方法稱為「工具方法」(Utility Methods)。
33
6-2-3 物件的使用介面 - 成員方法 (範例) 第6-2-2節程式範例只提供設定時間資料的setTime()方法,在這一節的程式範例將新增取得時間資料的方法,如下所示: public int getHour(){ return hour; } public int getMinute(){ return minute; } public int getSecond(){ return second; } 上述3個方法可以取得物件時間資料的小時、分鐘和秒數,此時的類別成員資料已經擁有完整的存取介面,至於成員資料的資料型態是什麼?已經不重要!因為資料本身已經被類別完全封裝起來。
34
6-3 類別的建構子 6-3-1 類別的建構子 6-3-2 使用this參考物件本身
35
6-3-1 類別的建構子-說明 Java基本資料型態在宣告變數時會配置所需的記憶體空間,至於類別型態的變數並不會自動建立物件,如果類別沒有建構子,在使用new運算子建立物件時,只會配置所需的記憶體空間,但是,並不會指定實例變數的初值。 如果希望如同基本資料型態在宣告時能夠指定變數初值,在類別宣告需要新增建構子,建構子是物件的初始方法,在建立物件時就會自動呼叫此方法。
36
6-3-1 類別的建構子-物件壽命 從物件使用new運算子建立物件到物件不再使用的期間,稱為「物件壽命」(Object Lifetime),因為Java擁有垃圾收集(Garbage Collection)功能負責處理不再使用的物件,程式設計者並不用自行處理,只需考量如何建立類別的建構子。
37
6-3-1 類別的建構子-特點 Java的建構子擁有一些特點,如下所示: 建構子與類別同名,例如:類別Time的建構子方法是Time()。
建構子沒有傳回值。 建構子支援方法的「過載」(Overload),詳細的說明請參閱第4章,也就是說可以擁有多個同名的建構子方法,只是擁有不同的參數型態和參數個數,如下所示: Time(); Time(int h, int m, int s);
38
6-3-1 類別的建構子-UML類別圖 在UML類別圖的建構子也是位在方法清單,只是在前面加上<<constructor>>,如下圖所示:
39
6-3-2 使用this參考物件本身-使用在方法
在類別的成員方法可以使用this關鍵字參考物件本身的實例方法和變數,例如:參數列如果和實例變數名稱相同,我們可以使用this關鍵字指明是實例變數,如下所示: public boolean setTime(int hour,int minute,int second) { if ( validateTime(hour, minute, second) ) { this.hour = hour; this.minute = minute; this.second = second; return true; } else return false; }
40
6-3-2 使用this參考物件本身-使用在建構子
public Time() { this(12, 30, 10); } public Time(int m) { this(12, m, 10); } public Time(int h, int m) { this(h, m, 10); } public Time(int hour, int minute, int second) { ………. }
41
6-4 使用物件的成員資料-說明 Java類別的成員資料除了使用基本資料型態的變數外,也可以使用其它物件的物件變數,例如:Customer類別宣告中有Date物件,如下所示: class Customer { private int id; private char rank; private Date birthday; public Customer(int id,char r,int m,int d,int y) { } public void printCustomer() { } }
42
6-4 使用物件的成員資料-注意事項 請注意!物件變數的內容只是指向物件的參考指標,並沒有真正建立物件,所以建構子需要使用new運算子建立物件,如下所示: birthday = new Date(m, d, y);
43
6-5 在物件使用類別變數與方法-說明 在本節之前的類別宣告都沒有使用static宣告的變數和方法,因為在類別宣告static的類別變數和方法後,建立物件並不會替每一個物件實例建立獨立的類別變數和方法,只有不是宣告成static部分才會建立獨立的實例變數和方法。 類別變數和方法是屬於類別,所有物件都是使用同一份類別變數和呼叫同一個類別方法。
44
6-5 在物件使用類別變數與方法-範例 例如:Student類別擁有類別變數teacherNo、count和類別方法getStudentCount(),如下所示: class Student { public static int teacherNo = 500; private static int count; ………... ………… public static int getStudentCount() { return count; } ……….. }
45
6-5 在物件使用類別變數與方法-UML類別圖
在執行Ch6_5.java的Java程式建立的UML類別和物件圖,如下圖所示:
46
End
Similar presentations