Tina Tang's Blog

在哪裡跌倒了,就在哪裡躺下來

0%

Java筆記(2)-介面和抽象

了解 Java 中的介面(interface)抽象(abstract)


介面

介面可以被理解為「接口」,讓外部可以透過這個接口與內部作溝通。而「接口」通常都是有著某些特定形態的,只有收發雙方都有一樣的「接口」,接口才能被有效使用。介面作為接口,規範了方法能被外部使用的規則。

在程式設計中,我們可以透過介面來設定我們想被外部使用的規則,一是可以為每個需要的類別設定一樣的規則,二是避免把不應公開的內部程式碼對外公開。

介面(interface)的方法都是抽象(abstract)公開(public)的,以及其屬性全部都為常數(const),介面本身不實作方法,而是為了被外部使用,因此方法都必定是公開的。

範例

1
2
3
4
5
interface USB {
public static final int a = 5;
public abstract void execute();
public abstract void stop();
}

不過這邊有個小技巧,由於介面裡面的屬性和方法一定「全部」都是「常數」和「抽象方法」,也一定要是 public 的,因此所有的修飾子都可以省略不寫:

1
2
3
4
5
interface USB {
int a = 5;
void execute();
void stop();
}

以下是一個類別實作(implements) USB 介面的方式,介面中的所有方法都必需被實作。亦即表示,介面變成了類別的規範。

1
2
3
4
5
6
7
8
9
10
11
12
13
Class Mouse implements USB {
private String state;
private int countClick;
public void execute() {
this.state = "start";
}
public void stop() {
this.state = "stop";
}
private void countClicking() {
this.countClick += 1
}
}

只要我們的類別需要用到 USB,我們就可以把 USB 介面實作到類別中。當介面作出改動時,所有實作該介面的類別都會收到訊息,以保實所有實作介面的類別都合符介面提出的規範。

但我們要注意的是,介面不一定是要能被重複使用的。換句話說,不是必需要可以被用在多個類別上時我們才使用介面,即使每個類別都有屬於自已的介面也是可以的,重點在於不要過度設計。


抽象

抽象類別

抽象類別不能建立實體,專門用來被繼承
抽象類別(Abstract Class)是很容易與介面搞混的概念,但他們其實是有很大的不同。抽象類別是不能直接實例化的類別抽象類別是用來被繼承的

擁有這個概念的類別,繼承抽象類別,在程式撰寫上就可以利用多型的概念上程式更有邏輯性。舉例來說,Animal 這個抽象的概念不應該被實體化,因為現實中不存在一種東西叫作「動物」,而狗、鳥、魚都是實際存在的東西,都擁有「動物」這個概念的特性。

抽象類別範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
abstract class Animal {
// 成員定義
}

class Dog extends Animal {
// 成員定義
}

class Bird extends Animal {
// 成員定義
}

class Fish extends Animal {
// 成員定義
}

抽象方法

抽象方法只能定義原型,專門用來被覆寫
抽象方法只能寫方法的原型,無法定義方法的本體,抽象方法只能定義在抽象類別中。

  • 方法的原型:只定義修飾子、回傳值型態、方法名稱、參數型態,而沒有大括號 {} 的部分就是方法原型。
  • 方法的本體:就是用大括號 {} 定義的東西,有寫 {} 就算有定義,不管裡面有沒有程式敘述。

抽象方法(方法的原型)範例:

1
2
abstract <修飾子> 回傳型態 方法名稱(<參數...>);
abstract void eat();

因為抽象方法只能定義方法的原型,所以必須要有子類別「覆寫」這個抽象方法。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
abstract class Animal{
int weight,heigh;
void setValue(int w,int h){
this.weight = w;
this.height = h;
}
abstract void eat();
}
class Dog extends Animal{
void eat(){
System.out.println("啃骨頭...");
}
}
class Bird extends Animal{
void eat(){
System.out.println("早起吃蟲...");
}
}

介面 vs 抽象類別

  • 相同:
  1. 介面和抽象類別都無法直接被實例化(實體化)
  2. 介面和抽象類別中的抽象方法都必須被實作(被覆寫)
  • 相異:
  1. 介面是用來被類別實作(extends)的,抽象類別是用來被類別繼承(extends)的。
  2. 抽象類別中可以定義抽象方法非抽象方法,而介面中只能定義抽象方法

參考資料

Java備忘筆記
物件導向中的介面與抽象類別是什麼?