物件導向的三大特型:封裝、繼承、多型。

不過或許我們應該先來講類別和物件的關係。

在物件導向的世界裡,很多東西都是由一個一個物件構成的。舉凡一些感覺很「具體」的東西都可以是物件,例如房子、Xperia Z5、杯子、橡皮擦、哈士奇、Noob……等等,而類別通常是一些比較籠統的東西,例如車、人、飛機之類的。

雖然也沒有規定那些東西一定是物件或類別,不過通常我們會在類別裡定義它的特性,並透過這個類別來建立一個物件。

類別

類別比較算是一個範本,裡面定義好該有的屬性方法,其中方法又大概可以分為一般的方法類別方法建構子。例如我們可以定義一個學生類別,裏面包含了namescore 屬性,以及 getName() 方法、setScore() 方法。

物件

物件則是實體的東西,由定義好的類別來建立一個物件。例如 Peter 是一個學生、Amy 是一個學生。

那麼 Peter 就會擁有 Student 類別的屬性和方法,所以 Peter 會有 namescore 屬性、getName()setScore() 方法,Amy 也會有自己的 namescore 屬性、getName()setScore() 方法。

類別與物件

來寫個範例:

class Student{
    public String name;
    public int score;
    public void getName(){
        return name;
    }
    public void setScore(int s){
        score = s;
    }
}

public class class_test{
    public static void main(String[] agrs){
        Student Peter = new Student();
        Peter.setName("Peter");
        Peter.score = 88;
        Student Amy = new Student();
        Amy.setName("Amy");
        Amy.score = 85;
    }
}

不過,建立一個物件後,就得手動給屬性,還是有點麻煩。在類別裡面放建構子,就可以在建立物件的時候,把所有屬性一次給完。

建構子的寫法大概是這樣:

Student(String n, int s){
    name = n; score = s;
}

值得注意的是,建構子前面不得加任何修飾,而且名字要和類別名稱一模一樣。

最後要講的是類別方法,類別方法又稱靜態方法,所以宣告方法的時候加一個 static 就可以了。類別方法撰寫的方式和一般的方法基本上一樣,只是呼叫的時候,不需要建立物件就可以呼叫了。

把上面的範例加上建構子和類別方法大概是這樣:

class Student {
    public String name;
    public int score;
    Student(String n, int s) {
        name = n;
        score = s;
    }
    public void getName() {
        return name;
    }
    public void setScore(int s) {
        score = s;
    }
    public static void helloWorld() {
        System.out.println("Hello, World!");
    }
}
public class class_test {
    public static void main(String[] agrs) {
        Student Peter = new Student("Peter", 88);
        Student Amy = new Student("Amy", 85);
        Student.hellowWorld();
    }
}

這樣就是最基本的類別和物件之間的關係了。

物件導向的封裝性

封裝(Encapsulation),簡單來說就是抽象(Abstract)的概念。對一件事情只需要理解他的外在就好,不需要了解裡面內部的構造。 就像我們只要知道看電視的時候該怎麼轉台、調音量,並不需要知道裡面有多少電線和構造。

而我們在寫類別的時候,把類別定義完,之後要寫物件就只要指定屬性和方法就好,並不需要知道方法是怎麼實作的。這也是一種封裝性。

物件導向的繼承性

繼承(Inheritance),要設計一張和原有設計很像的設計圖,可以拿原本的設計圖當底開始畫。 這樣就不需要把相同的東西再宣告一次。

比方說一個經典的例子,如果有一個 Car 類別:

class Car {
    public String plate;
    public String brand;
    public String color;
}

記載了車牌、廠牌、顏色三個屬性。如果要多新增一個 Taxi 類別,可以直接繼承 Car 屬性來用:

class Taxi extends Car {
    public String plate;
    public String brand;
    public String color;
    public String driver;
}

這就是經典的計程車繼承車 XD。

物件導向的多型性

多型(Polymorphism),簡單來說就是同名的方法。多個相同名稱的方法,傳入不同的參數,會執行不同的敘述。 比方說,一個計算面積的方法,如果傳入一個參數,就當正方形來算面積;傳入兩個參數,就當成長方形來算面積。

public int computeArea(int length) {
    return length * length;
}
public int computeArea(int length, int width) {
    return length * width;
}

其實多型包含多載(Overloading)和複寫(Overriding),不過暫時知道多載就好了。

以上就是物件導向的三個特性,不過,物件導向協助我們解決了什麼樣的問題? 以下引用 Ruby 使用手冊:

物件導向程式設計能夠將單調而重複的邏輯工作委派予資料,把我們對資料的概念從被動轉為主動。換而言之,

  • 資料不再是一個開蓋盒子,只能讓我們自己去找東西或放東西進去。
  • 資料變成是能夠運作的機器,具有標示明確的開關與功能。

上述的「機器」內部可能非常複雜,也可能非常簡單,並不能單以外部作出判斷,我們不會隨意拆開機器(除非我們非常確定設計出現問題),所以我們只需要按按開關,了解有甚麼功能可以與資料互動。機器做好後,我們就不會再去想它是如何運作了。

好啦 Java 筆記暫時整理到這邊,大概也沒時間補充了 QQ。

我要學會 Java 目錄