Java 快速導覽 - 物件導向概念

Java 的物件導向程式設計 (object-oriented programming) 中,除了程式都以物件 (object) ,也就是以關鍵字 class 定義的類別 (class) 所組成外,每一個物件都具具有型態 (type) ,這就好像日常生活中哪一種、哪一類東西一般,例如這種長方形裡頭有許多頁文字,然後上下有封面裝訂在一起的的叫做「書本」,那種四開大小疊在一起的有文字紙張叫做「報紙」。



如果要在程式當中設計「書本」跟「報紙」的類別,兩者具有共通的特性,不外是紙張、文字、圖片等,此時物件導向提供一個避免重複程式碼的方法,也就是利用子類別 (subclass) 去繼承 (inherit) 父類別 (superclass) ,這樣一來,共通的程式碼都可以放在父類別之中,無須每一個類別都重複相同的程式碼。


「繼承」是物件導向程式設計中一個重要也是核心的觀念,動詞原文為 inherit 。雖然 inherit 在英文的意思泛指從什麼得到什麼,用作中文「繼承」說得通,也能用作「遺傳」。然而中文的「繼承」隱含某物不再,另物將起的意思,譬如「我繼承某某的精神」,雖然某某不見得已死,未來將要付出努力的卻是我而非某某。因而這裡的意思中文用「遺傳」比較恰當,子代會從親代遺傳某些生物特性,子代與親代也會並存一段時間,這就沒有某物不再的意含了。然而這裡我們仍沿用程式設計常用的「繼承」一詞,但仍提出意見以免讀者混淆。


我們以下用個簡單的範例說明繼承的使用
class Animal {
    int age;
    int weight;
    
    void speak() {
        System.out.println("哈囉,我已經" + age + "歲,有" + weight + "公斤重");
    }
}

class Elephant extends Animal {
    String name;
    
    void speak() {
        System.out.println("我的名字是" + name + "已經" + age + "歲");
    }

}

class JungleDemo1 {
    public static void main(String[] args) {
        Animal puppy1 = new Animal();
        puppy1.age = 12;
        puppy1.weight = 25;
        puppy1.speak();
        
        Elephant puppy2 = new Elephant();
        puppy2.age = 8;
        puppy2.weight = 1200;
        puppy2.name = "大象";
        puppy2.speak();
    }
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:JungleDemo1.java
    功能:示範物件導向的基本觀念 
    作者:張凱慶
    時間:西元 2010 年 10 月 */


編譯後執行,結果如下



首先, Animal 為我們設計的父類別,因此每一個以 Animal 建構的物件,或是繼承自 Animal 的物件都會有整數 int 型態的 age 及 weight 屬性 (field) ,以及 speak() 方法 (method) 。


Elephant 為我們設計的子類別,注意第 10 行
class Elephant extends Animal {


關鍵字 extends 標示 Elephant 繼承自 Animal ,注意, Java 的子類別只能繼承自單一父類別,但可以實作多個不同介面 (interface) ,這所謂的介面像是共通的規格,我們往後才會詳加介紹。


我們添加了 name 屬性,這是 Elephant 所專有的,父類別 Animal 並不具有 name ,子類別 Elephant 的屬性包含 Animal 的 age 及 weight 。 extends 過父類別的東西,子類別就不必贅述一次,也就是無須寫重複的 age 及 weight 。


留意父類別 Animal 有個 speak() 方法,子類別也有個 speak() 方法,繼承的規則是父類別有的,子類別也都會有,但是子類別可以增加專屬的屬性或方法,這裡卻出現相同名稱的方法,這裡是子類別改寫 (override) 父類別原先設計的方法。若是沒有改寫,子類別會一字不改的延續使用父類別的方法,改寫的原因通常是子類別具有其他特性,如此例中 Elephant 多了 name 屬性。


第 21 行到第 30 行
Animal puppy1 = new Animal();
puppy1.age = 12;
puppy1.weight = 25;
puppy1.speak();
        
Elephant puppy2 = new Elephant();
puppy2.age = 8;
puppy2.weight = 1200;
puppy2.name = "大象";
puppy2.speak();


第 21 行宣告同時建立 Animal 型態的 puppy1 ,其後第 22 行及第 23 行利用句點運算子 (dot operator) 設定屬性 age 及 weight 的值,最後在第 24 行呼叫 speak() 方法。


第 26 行則是宣告同時建立 Elephant 型態的 puppy2 ,其後的過程類似。注意,這裡是簡單說明 Java 程式可以這樣寫,但沒有用到封裝 (encapsulation) 的特性,會使資料在程式中任意被存取,我們稍後會繼續解釋如何進行封裝,達到良好的資訊隱藏 (information hiding) 。


由於設計類別就等於設計型態, Java 程式由一堆以類別為藍本的物件組成,因此具有非常多不同的型態,如果有效利用各種型態,就是物件導向另一個重要觀念,也就是多型 (polymorphism) 。關於多型,我們稍後會詳細說明。


中英文術語對照
物件導向程式設計object-oriented programming
物件object
類別class
型態type
子類別subclass
繼承inherit
父類別superclass
屬性field
方法method
介面interface
改寫override
句點運算子dot operator
封裝encapsulation
資訊隱藏information hiding
多型polymorphism






沒有留言: