物件導向(Object-oriented programming)是程式開發的抽象方針,將物件作為程式的基本單元,將程式和資料封裝其中,以提高軟體的重用性、靈活性和擴充性。
類別(class)
類別(class)是建立物件(object)的藍圖,內部定義了具體的屬性(attribute)和方法(method),一旦類別做了實體化(new)的動作之後,就可以產生物件(object),這個具體的物件就會擁有該類別所定義的屬性,並且可以執行該類別所定義的方法。
類別可能包括:
- 屬性(attribute):變數(variable),需要記憶的資訊。
- 方法(method):函式(function),能夠提供的服務。
- 建構子/建構函式(constructor):設定初始化的函式(function)。
- 建構子是「不可以」宣告回傳值型態,即使寫 void 也不行。
- 建構子名稱需和該類別(class)同名。
建構子的多載(overload)
多載(overloading):
- 函數名稱相同,引數個數不同
- 引數個數相同,引數型態(type)不同
相似功能的函數,以相同的名稱來命名之;透過不同的引數個數,或是不同的型態,來執行相對應的功能。
範例程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class Dog { String type; String color; Integer age; Integer weight;
public Dog() { this.type = "米格魯"; }
public Dog(String type, String color, Integer age) { this.type = type; this.color = color; this.age = age; }
public Dog(String type, Integer age, Integer weight) { this.type = type; this.age = age; this.weight = weight; } }
public class Main { public static void main(String[] args) { Dog dog1 = new Dog("黃金獵犬", "金毛", 7); Dog dog2 = new Dog(); Dog dog3 = new Dog("薩摩耶", 5, 20);
System.out.println("type:" + dog1.type + " color:" + dog1.color + " age:" + dog1.age + " weight:" + dog1.weight); System.out.println("type:" + dog2.type + " color:" + dog2.color + " age:" + dog2.age + " weight:" + dog2.weight); System.out.println("type:" + dog3.type + " color:" + dog3.color + " age:" + dog3.age + " weight:" + dog3.weight); } }
|
執行結果:
1 2 3
| type:黃金獵犬 color:金毛 age:7 weight:null type:米格魯 color:null age:null weight:null type:薩摩耶 color:null age:5 weight:20
|
物件(object)
物件是實體的,由定義好的類別去建立一個物件,並將它實例化,可以是一個變數或是一個函式。
物件可能包括:
- 屬性(attribute):變數(variable),需要記憶的資訊。
- 方法(method):函式(function),能夠提供的服務。
延續上面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class Dog { String type; String color; Integer age; Integer weight;
public Dog() { this.type = "米格魯"; }
public Dog(String type, String color, Integer age) { this.type = type; this.color = color; this.age = age; }
public Dog(String type, Integer age, Integer weight) { this.type = type; this.age = age; this.weight = weight; }
public String getDogInfo() { return "type:" + type + " color:" + color + " age:" + age + " weight:" + weight; } }
public class Main { public static void main(String[] args) { Dog dog1 = new Dog("黃金獵犬", "金毛", 7); Dog dog2 = new Dog(); Dog dog3 = new Dog("薩摩耶", 5, 20);
System.out.println(dog1.getDogInfo()); System.out.println(dog2.getDogInfo()); System.out.println(dog3.getDogInfo()); } }
|
執行結果:
1 2 3
| type:黃金獵犬 color:金毛 age:7 weight:null type:米格魯 color:null age:null weight:null type:薩摩耶 color:null age:5 weight:20
|
有了 Dog 這個類別之後,可以產出很多 Dog 資料(dog1, dog2, dog3…),每個 Dog 都是物件,每一個物件是獨立的個體,彼此互不影響。
物件導向的三大特性
物件導向的三大特性包括:封裝(Encapsulation)、繼承(Inheritance)、多型(Polymorphism)。
封裝(Encapsulation)
所謂封裝(Encapsulation),是指類別的設計者可以指定其他的類別能否存取自己的某個 member,也就是存取範圍的控制(對外的開放程度)。
封裝包含了兩個重要的觀念:
- 控制物件和外部進行互動的出入口
- 隱藏物件內部的細節資訊
Java 定義了四種存取範圍:
- private:只有 自己才可以存取,使用關鍵字
private
。
- package:只有和自己同一個 package 的 class 才可以存取,沒有相對應的關鍵字。
- protected:只有同一個 package 或是 自己的子類別才可以存取,使用關鍵字
protected
。
- public:所有的 class 都可以存取,使用關鍵字
public
。
如果 member 的前面沒有 private / protected / public
其中一個修飾字,則該 member 的存取範圍就是 package。從以上的敘述,讀者可以推知這四種存取範圍的大小是:
public > protected > package > private
繼承(Inheritance)
子類別(sub class)可以繼承父類別(super class)的屬性和方法,而不需重新定義,有程式碼再利用的概念。
- 每個子類別只能有一個父類別,而父類別可擁有一個以上的子類別。
- 兩者之間的關係可以用「is a」表示:SmartPhone(子類別) is a Product(父類別)。
- 透過關鍵字
extends
繼承來自父類別的 member。
多型(Polymorphism)
多型(Polymorphism)可以分為兩種類型:
- 編譯時多型 - 多載(Overloading)。
- 執行時多型 - 覆寫(Overriding)。
多載(Overloading)
有多個相同名稱的方法,但是傳入不同的參數就會執行不同的敘述。
範例:
1 2 3
| public void setDogInfo(String type, String color, Integer age, Integer weight) public void setDogInfo(String type, String color, Integer age) public void setDogInfo(String type, Integer age, Integer weight)
|
再使用前面的 Dog class 舉例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| public class Dog { String type; String color; Integer age; Integer weight;
public Dog() { this.type = "米格魯"; }
public Dog(String type, String color, Integer age) { this.type = type; this.color = color; this.age = age; }
public Dog(String type, Integer age, Integer weight) { this.type = type; this.age = age; this.weight = weight; }
public String getDogInfo() { return "type:" + type + " color:" + color + " age:" + age + " weight:" + weight; }
public void setDogInfo(String type, String color, Integer age, Integer weight) { this.type = type; this.color = color; this.age = age; this.weight = weight; }
public void setDogInfo(String type, String color, Integer age) { this.type = type; this.color = color; this.age = age; }
public void setDogInfo(String type, Integer age, Integer weight) { this.type = type; this.age = age; this.weight = weight; } }
public class Main { public static void main(String[] args) { Dog dog1 = new Dog(); Dog dog2 = new Dog(); Dog dog3 = new Dog();
dog1.setDogInfo("黃金獵犬", "金毛", 7); dog2.setDogInfo("薩摩耶", 5, 20); dog3.setDogInfo("米格魯", "金毛", 3, 15);
System.out.println(dog1.getDogInfo()); System.out.println(dog2.getDogInfo()); System.out.println(dog3.getDogInfo()); } }
|
執行結果:
1 2 3
| type:黃金獵犬 color:金毛 age:7 weight:null type:薩摩耶 color:null age:5 weight:20 type:米格魯 color:金毛 age:3 weight:15
|
覆寫(Overriding)
子類別可以覆寫父類別的方法,使其擁有不同於父類別的行為。
父類別範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Animal { String type;
public Animal() { this.type = "貓"; }
public String getInfo() { return "動物資料: type:" + type; }
public void setType(String type) { this.type = type; } }
|
子類別範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Dog extends Animal { String species; String color; Integer age; Integer weight;
public String getInfo() { return "小狗資料: type:" + type + " species:" + species + " color:" + color + " age:" + age + " weight:" + weight; }
public void setInfo(String species, String color, Integer age, Integer weight) { this.species = species; this.color = color; this.age = age; this.weight = weight; } }
|
Main 函式範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Main { public static void main(String[] args) { Animal animal = new Animal(); Dog dog = new Dog();
dog.setType("狗"); dog.setInfo("米格魯", "金毛", 3, 15);
System.out.println(animal.getInfo()); System.out.println(dog.getInfo()); } }
|
執行結果:
1 2
| 動物資料: type:貓 小狗資料: type:狗 species:米格魯 color:金毛 age:3 weight:15
|
原本父類別的 getInfo() 方法只能取得 type。
因子類別覆寫了父類別的 getInfo() 方法,可取得 type、species、color、age 和 weight。
參考資料
物件導向(Object-oriented programming)
Java 學習系列