第五章 物件導向技術的基本觀念 - 人生紀錄本 - udn部落格
人生紀錄本
作家:宋坤祐
文章分類
    Top
    第五章 物件導向技術的基本觀念
    2021/05/10 11:01:22
    瀏覽:3139
    迴響:0
    推薦:0
    引用0

    所謂的「物件導向程式設計」(OOP, Object-Oriented Programming,包括了「物件導向」與「程式設計」兩種技術的整合,在西元1980年代,物件導向技術影響了很多資訊科學的領域,產生的結果多半是正面的,其實物件導向的觀念起源得更早,只是到近年來才逐漸地被理論化和系統化,並導入各種領域中加以運用。程式設計是很多人都曾有過的經驗,目的是要指揮電腦來解決問題,不同的程式語言往往提供了不同方法來解決問題,而「物件導向程式語言」(Object-Oriented Programming Language)所提供的方法就是建立在物件導向的基礎上。Java算是一種命令式的物件導向程式語言,本章透過Java語言來了解物件導向的程式設計。

    5-1-1

    5-1-2

    1. 分類可以將複雜的事物釐清。

    2. 「類別」(Class)是用來將物件分類的。

    3. 屬於同一類別的物件具有很多相同的特徵。

    4. 也可以說類別是鑄造物件的模子,物件則是類別的案例(Instance)。

    5-2-1 物件導向程式設計的基本觀念

    1. 物件導向程式設計的精髓在於類別(class)與物件(object)的運用。

    2. 通常程式設計所產生的是對於現實事物的一種描述。

    3. 電腦系統在目前的科技下就是得接受「抽象描述」(abstraction)。

    4. Java是一種程式語言,支援抽象描述的能力,所用的就是類別與物件。

    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 EstimatePriceCar類別的方法成員

    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關鍵字,代表該成員一旦有了數值,在類別所有的物件中,都指定成該數值。 finalfinal修飾元用來指定成員屬性的值為常數,或是指定成員方法在子類別中不被變更(Overridden)

    synchronizedsynchronized 修飾元強制系統在任一時刻,僅有一個程序或執行緒(Thread) 在執行被修飾的方法,由於Java 支援多執行緒同時執行,有可能在同一時刻,好幾個執行緒都執行同一個類別方法,假如不希望這種情況發生,就可以在方法前加上synchronized 的修飾元。 nativenative 修飾元則是告訴系統某個方法的實際執行碼是用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即是利用物件導向的概念實行的方法

    回應
    發表迴響

    會員登入