本文是系列文章「Java 初階篇」的第四章,介紹物件導向程式設計。
物件導向程式設計(Object Oriented Programming)是一種具有物件概念的程式設計典範,我們真實世界中的事物都可以抽象化為物件,例如鍵盤、汽車、畫筆等等,在腦子裡描述物件的這個過程就是抽象化。物件導向程式設計的優點大致有程式易讀易懂、易維護、支持更大的系統、多人合作等等。
1. 封裝
把某事物抽象化為物件之後,裡面有些資訊想要隱藏起來不給外部使用,只公開一些方法讓外部使用。
例如:
class 蛋糕販賣機{
private int 蛋糕數量;
......
private boolean 會員確認(會員卡、密碼){
......
}
private void 投出蛋糕(){
......
}
public void 買蛋糕(會員卡、密碼){
if(會員確認(會員卡、密碼) == true)
投出蛋糕();
......
}
public void 查詢會員(會員卡、密碼){
......
}
......
}
利用修飾子 private、public,把各內容做公開或隱藏,讓使用者只能使用某些方法。
1.1 存取修飾子
- public:公開,任何人都可存取。
- protected:保護,只有該類別的子類別才可存取。
- no modifier:預設,只有同一個 package 之中的類別才可存取。
- private:私有,只有自己類別的成員才可存取。
比較表:
| Class | Package | Subclass(same pkg) | Subclass(diff pkg) | World | |
|---|---|---|---|---|---|
| public | V | V | V | V | V |
| protected | V | V | V | V | X |
| no modifier | V | V | V | X | X |
| private | V | X | X | X | X |
via stackoverflow
2. 繼承
用物件導向來想像貓跟動物的話,在我們的真實世界中,貓是一種動物,具有動物的屬性與方法,以及只有貓才有的屬性與方法,動物就是父類別(super class),貓就是子類別(sub class),貓繼承了動物的屬性與方法,所以子類別會繼承父類別的屬性與方法,同時也擁有自己的屬性與方法,也就是說子類別就是父類別的延伸(extend)。
在 Java 中,要用關鍵字extends來表示繼承關係:
class 子類別 extends 父類別{
......
}
例如:
class 動物{
int 體重;
int 年齡;
......
void 叫(){
......
}
......
}
class 貓 extends 動物{
void 吃(){
......
}
void 睡(){
......
}
......
}
3. 多型
利用父類別提供的方法,子類別也可以有自己獨特的行為。
例如:
class 動物 {
void 叫() {
System.out.println("啊啊啊!");
}
}
class 貓 extends 動物 {
void 叫() {
System.out.println("喵喵喵!");
}
}
class 狗 extends 動物 {
void 叫() {
System.out.println("汪汪汪!");
}
}
class 鳥 extends 動物 {
void 叫() {
System.out.println("啾啾啾!");
}
}
class Test {
public static void main(String[] args) {
動物 a =new 動物();
動物 b =new 貓();
動物 c =new 狗();
動物 d =new 鳥();
a.叫();
b.叫();
c.叫();
d.叫();
}
}
輸出結果:
啊啊啊!
喵喵喵!
汪汪汪!
啾啾啾!
4. 抽象
關鍵字 abstract(抽象)可以用來修飾類別與方法。
4.1 抽象類別
例如:
abstract class 動物{
int 體重;
int 年齡;
......
void 叫(){
......
}
......
}
class Test {
public static void main(String[] args) {
動物 a = new 動物();
}
}
此時會編譯錯誤,因為抽象類別無法被實體化,但可以被繼承。
例如:
abstract class 動物 {
......
}
class 貓 extends 動物 {
......
}
class 狗 extends 動物 {
......
}
class 鳥 extends 動物 {
......
}
動物是一個概念,是抽象的,不能被實體化,而貓、狗、鳥是實際存在的,可以繼承動物的特性。
4.2 抽象方法
把方法變成抽象方法,只能定義其原型,但可以被覆寫。
例如:
abstract class 動物{
int 體重
int 年齡
abstract void 吃();
}
class 貓 extends 動物{
void 吃(){
System.out.println("吃魚......");
}
}
class 狗 extends 動物{
void 吃(){
System.out.println("吃雞腿......");
}
}
抽象的「動物」類別中,有抽象的「吃()」方法,強制繼承「動物」的子類別必須實作自己的「吃()」方法,同時也擁有「動物」定義的成員。
需注意抽象方法只能定義在抽象類別中。
5. 介面
看完上面的 abstract(抽象),就可以知道如果想要減少重複的程式碼,又想要子類別可以有方法規範,則可使用 abstract(抽象)。
如果想要只規範子類別的方法時,或者想要同個子類別實作多個不同的介面(多重繼承),則可使用 interface(介面)。
5.1 宣告
宣告:
(修飾子) interface 介面名稱 {
......
}
例如:
public interface 進食{
void 吃();
}
public interface 飛行{
void 飛();
}
5.2 實作
關鍵字 implements 可讓類別實作介面,而類別需要定義該介面所制定的方法。
class 貓 implements 進食 {
public void 吃(){
System.out.println("貓可以吃食物!")
}
}
class 鳥 implements 飛行 {
public void 飛(){
System.out.println("鳥可以飛!")
}
}
class 老鷹 implements 進食, 飛行 {
public void 吃(){
System.out.println("老鷹可以吃食物!")
}
public void 飛(){
System.out.println("老鷹可以飛!")
}
}
進食 a = new 貓();
a.吃();
輸出結果:
貓可以吃食物!