字體:小 中 大 | |
|
|
2021/05/10 11:01:22瀏覽2386|回應0|推薦0 | |
所謂的「物件導向程式設計」(OOP, Object-Oriented Programming),包括了「物件導向」與「程式設計」兩種技術的整合,在西元1980年代,物件導向技術影響了很多資訊科學的領域,產生的結果多半是正面的,其實物件導向的觀念起源得更早,只是到近年來才逐漸地被理論化和系統化,並導入各種領域中加以運用。程式設計是很多人都曾有過的經驗,目的是要指揮電腦來解決問題,不同的程式語言往往提供了不同方法來解決問題,而「物件導向程式語言」(Object-Oriented Programming Language)所提供的方法就是建立在物件導向的基礎上。Java算是一種命令式的物件導向程式語言,本章透過Java語言來了解物件導向的程式設計。 5-1-1 5-1-2
5-2-1 物件導向程式設計的基本觀念
5-2-2 從程式執行詮釋物件的觀念 基本觀念: 物件是類別的案例 (instance)。 類別像是建立物件的架構或模子。 在 Java 程式執行的過程中擔當大任的主要是物件。 在使用前,物件必須先被生產出來。 物件建立的步驟: 參考變數 (reference variable)的宣告, (declaration) 產生物件 參考變數(reference variable)的宣告: 物件的內容可多可少,當我們指名物件時,無法以其內容來分辨。 Java 採用物件參考值 (object reference value) 來指名某一個物件,有點像 C/C++ 裡頭指標和位址的觀念。在建立物件以前,我們得用物件參考變數來宣告物件在程式裡頭的名稱。 產生物件: 利用建構子(constructor)來產生類別案例,也就是物件。 關鍵字 new會指示系統傳回一個指定類別所屬物件的參考值,當做參考變數的值。 由於建構子是一個程序,物件產生過程中物件本身的一些成員是利用建構子的執行而建立的。 宣告和案例化兩個步驟在語法上也可以合併在一起。 由於物件移到記憶體之後占用了空間,最好能回收。 5-2-3 物件的成員與類別的成員 基本觀念: 物件是類別的案例,擁有了類別中定義的屬性與方法,這些都是物件的成員( 可稱之為 instance member)。 物件的屬性成員具有指定的值,方法成員則是同一類別的所有物件都一樣的。 基本觀念: 物件的屬性成員決定了物件的狀態(state),每個物件的狀態決定於其屬性成員所具有的「值 (value)」。 類別可以具有不屬於任何物件的屬性成員,我們把它叫做靜態成員 (static member)。 靜態成員的處理可以透過類別名稱或是該類別的物件的名稱來進行。 與物件成員和靜態成員相關的名詞 「句點表示法」(dot notation): 程式中對於各種成員的利用,必須遵循語法與規則。 通常我們可以透過方法的呼叫 (method invocation)來觀察物件所表現的行為。 所謂的「句點表示法」(dot notation)就是常用的呼叫方法的語法。 5-3-1 Java類別的基本語法 基本觀念: 用物件導向程式語言來寫程式通常都要從撰寫類別的定義開始。 了解如何從類別的定義來產生物件。 把應用系統的邏輯放到物件的各種互動關係中。 一個簡單的Car 類別定義 // 一個簡單的Car類別定義 class Car { //Car是類別名稱 String model; //model, year, color均為屬性 int year; String color; void EstimatePrice() { //void EstimatePrice是Car類別的方法成員 if (year > 1985) { System.out.println("This car costs more than 250000 dollars.\n"); } else { System.out.println("This car costs less than 250000 dollars.\n"); } } } 「存取修飾元」(Access Modifier): 預設的(Default):在同一個Package中的類別,都能引用預設存取型態的類別成員。 公用的(Public):成員可被任何的類別與物件存取,沒有限制。 保護的(Protected):只有原類別或其子類別的方法能使用該成員。 私有的(Private):僅讓成員給原類別使用。 其他的修飾元: static:假如成員前多了static關鍵字,代表該成員一旦有了數值,在類別所有的物件中,都指定成該數值。 final:final修飾元用來指定成員屬性的值為常數,或是指定成員方法在子類別中不被變更(Overridden)。 synchronized:synchronized 修飾元強制系統在任一時刻,僅有一個程序或執行緒(Thread) 在執行被修飾的方法,由於Java 支援多執行緒同時執行,有可能在同一時刻,好幾個執行緒都執行同一個類別方法,假如不希望這種情況發生,就可以在方法前加上synchronized 的修飾元。 native:native 修飾元則是告訴系統某個方法的實際執行碼是用C語言撰寫的,例如: native int compute y2k( ); 定義子類別的方式 // 定義子類別的方式 class MyCar extends Car { //Car是父類別,MyCar是子類別,繼承Car的屬性 String LicensePlate; String Dealer; } 5-3-2「重訂」(Override) 與 「重載」(Overloading) 基本觀念: 子類別也可以變更繼承自父類別之方法的功能,我們把這種現象稱做「重訂」(Override)。 所謂的「重載」(Overloading)是指同樣的類別中含有多個名稱相同的方法,卻具有不同的功能,系統可從這些方法的呼叫參數來辨別其差異。 重訂與重載的方式 // 子類別變更繼承自父類別之方法的功能 class overRideCar extends Car { String LicensePlate; String Dealer; void EstimatePrice() { if (year > 1985) { System.out.println("This car costs more than 550000 dollars.\n"); } else { System.out.println("This car costs less than 550000 dollars.\n"); } } } // 重載的方式 class overloadCar extends Car { String LicensePlate; String Dealer; void accelerate() { System.out.println("Just accelerate!\n"); } void accelerate(int a) { System.out.println("Accelerate to 100 mph in "+a+" seconds!\n"); } } 測試「重訂」的觀念 class Test2 { public static void main(String args[ ]) { overRideCar ford = new overRideCar(); ford.year=1999; ford.model="Modeo"; ford.LicensePlate="CO-1211"; ford.EstimatePrice(); } } This car costs more than 550000 dollars. 測試「重載」的觀念 class Test3 { public static void main(String args[]) { overloadCar ford = new overloadCar(); ford.accelerate(); ford.accelerate(5); } } Just accelerate! Accelerate to 100 mph in 5 seconds! 5-3-3 抽象類別 (Abstract class) 的觀念 抽象類別代表僅含定義不含實際執行程式碼的類別。 通常抽象類別可用來萃取多種類別的共通性,在設計上比較方便。 抽象的方法 (Abstract method) 是不含執行程式碼的方法。 抽象類別與抽象方法的例子 abstract class job{ abstract void cjob(); } 抽象方法在使用上的限制: 建構子不能是抽象方法。 抽象方法不能和 static 或private用在一起。 Java支援所謂的「介面」(Interface)定義,可看成是類別定義的樣版,和抽象類別的概念很類似,但是「介面」定義中的方法成員完全不含程式碼,屬性成員僅限於常數 (Constant)。 Interface 的例子 interface job { abstract public void Major_jobs( ); } class FireFighter implements job { int JobCode; public void Major_jobs( ) { System.out.println(“Fight fire!\n”); } } 5-3-4 類別的繼承關係 我們可以利用現有類別來建立新的類別,新的類別除了繼承現有類別的屬性和方法之外,還可自行定義新的。 通化generalization: 在系統分析與設計的過程當中,不見得先有父類別,很可能先有子類別,萃取出共有的特性來定義父類別,這個過程稱作「通化」。 特化specialization: 若是先有父類別,再一一地定義出子類別,則叫做「特化」。 5-3-5 類別的繼承關係和物件的衍生關係 類別的繼承關係: 父類別的定義含有各種子類別的通化特性,也就是子類別們的共同點。 子類別的定義除了繼承父類別中的定義之外,還可以依個別的特性加入其他的定義。 簡易的類別架構 物件產生的兩個階段 宣告物件的資料型態:說明物件是由那種類別衍 生出來的。 建立物件:利用 new 關鍵字將物件建立起來。 類別的定義 // 類別r的定義 class r { int a; void f( ) {System.out.println("from r");} } // 類別s的定義 class s extends r { int b; void g( ) {System.out.println("from s");} 物件的衍生 class w { public static void main(String args[ ]) { r oR; s oS; oR=new r( ); oS=new s( ); oR.f( ); oS.g( ); oR.a= 23; oS.b= 34; oS.a=233; System.out.println("oR.a= " + oR.a); System.out.println("oS.b= " + oS.b); System.out.println("oS.a= " + oS.a); } } 5-3-6 Java中的各種類別 基本觀念: 類別和物件所描述的都是應用系統裡的實體或是抽象的觀念,其屬性可由基本值 (literal)與其他的物件參考所組成。 類別與物件和基本資料型態 (primitive date type)是不同的,通常都具有比較複雜的結構與功能, 所以對於應用系統的描述能力自然就較為優越。 Java完成的軟體系統會包含那些東西呢? 就是一群類別的集合。 連主程式也是某個類別中的一個方法,我們可以把整個系統看成是類別的組合。是大多數的系統都會善用現有的類別。類別之間的引用關係: 類別之間可能存在的引用關係。 除了利用繼承與聚集來產生新類別之外,也可以用 import將其他類別組成的包裹 (package)引入程式中,直接使用包裹中的類別。 這種類別再用的方式,再加上物件導向觀念的應用,使 Java 在程式設計的方法上提供了相當好的支援。 Java 中的各種類別 5-4-1 This 的用法 基本觀念: 定義類別時,除了要取名之外,還得訂出該類別的屬性與方法。 完成定義之後,類別就可以當做一種資料型態,用來宣告變數,這些變數會指向未來由類別所衍生的物件。 物件繼承了類別的屬性和方法,我們可以在程式中引用並執行物件所繼承的方法。 這些方法通常也叫做案例方法(instance method),和靜態方法(static method)是不一樣的。 為什麼需要this關鍵字? 在定義類別中的案例方法時.可能會發生一種情況,就是方法中的程式行引用到物件本身,這時候我們並不知道未來物件的名稱是什麼。 Java語法提供了this 關鍵字,讓我們能從案例方法的程式行中引用到物件本身。 This 的用法 class Cat { // 案例變數 (instance variables) int Weight; String Name; String Color; // 建構子 (constructor) public Cat(int Weight, String Name, String EyeColor) { String Color; this.Weight=Weight; Name=Name; Color=EyeColor; this.PrintCat(); PrintCat(); } void PrintCat ( ) { System.out.println(this); } } 區別參數名稱與屬性名稱 5-4-2 徹底了解物件與類別的特性 類別 a 的定義 class a { private int x; public int y; private void hi( ) { System.out.println("hi"); } public static void h( ){ System.out.println("h"); a d = new a( ); // 可以reference hi( ) d.hi( ); // 但需要在a的定義裡頭 } } 類別 b 的定義 class b { public static void main (String args[ ]){ a s = new a(); //s.hi( ); // no method matching hi() found in class a s.h(); a.h(); // cant make static reference to method void h( ) // if declared as : public void h( ) } } 類別 c 的定義 class c extends a { // void h( ) { }; // it is illegal to override a static method void g( ) { System.out.println(y); // System.out.println(x); // undefined variable x }; } // file saved as a.java, 用java b才有main執行 多層次的建構子 (multi-level constructors) class x { x( ) {System.out.println("from x !"); } } class y extends x { y( ) {System.out.println("from y !"); } } class z extends y { z( ) {System.out.println("from z !"); } } public class test { public static void main(String [ ] args) { z oz=new z(); } } 5-4-3 類別的多重繼承 5-4-4 抽象類別 (Abstract class) 的觀念 基本觀念: 物件建立的時候會占用系統的資源,我們必須明確地定義出物件的內容,讓系統知道如何建立物件,可以透過類別中建構子 (constructor) 的定義來達成。 當物件不必再用到的時候,也要把資源還給系統,這一部分的處理可以在類別中解構子(destructor) 的定義裡描述。 不再被任何物件變數引用的物件,系統有垃圾回收 (garbage collection) 的機制。 MyFamily 類別的定義(I) class MyFamily { int NumOfChildren; String NameOfSon; String NameOfDaughter; int CostPerChild; MyFamily() { this(2,"M","F"); } MyFamily(String Son) { this(2, Son,"F"); } ……… MyFamily 類別的定義(II) ……… MyFamily(int noc, String Son, String Daughter) { NumOfChildren = noc; NameOfSon = Son; NameOfDaughter = Daughter; CostPerChild = 5000; } public staticvoid main(String args[]) { MyFamily m = new MyFamily(); System.out.println(m.NameOfSon); MyFamily m1 = new MyFamily("Marty"); System.out.println(m8-NameOfSon); System.out.println(m8-CostPerChild); } } 重點整理: 1. 類別視為模子,利用模子鑄造出物件,這即是類別與物件的關係 2. 物件導向是一種觀念,也是一種方法, Java即是利用物件導向的概念實行的方法 |
|
( 知識學習|隨堂筆記 ) |