1. 程式人生 > >Android中的abstract 與interface

Android中的abstract 與interface

abstract , interface

// 抽象類
abstract class Abc {
// 抽象類中的抽象方法
public abstract void setData(int i);
public void Print() {
// 呼叫了抽象方法
setData(100);
}
}
// 該類繼承抽象類
class Bcd extends Abc {
@Override
public void setData(int i) {
System.out.print(i);
}
}
// 主類
class Main {
// 主方法
public Main() {
// 繼承抽象類的類必須實現抽象方法
// 除非繼承抽象類的型別也是抽象類
Bcd bcd = new Bcd();
bcd.Print();
}
// 另外一種情況
// 實現抽象類的時,必須實現類中抽象方法
Abc abc = new Abc() {
@Override
public void setData(int i) {
System.out.print(i);
}
};
}
// 抽象類
abstract class Server {
private int port;
// 抽象類中的抽象方法
public abstract void failure(String data);
public abstract void success(int code);
public void start() {
// ... start ...
if (true | false) {
success(String data);
} else {
failuer(int code);
}
}
}
// 主類
class Main {
public Main() {
Server server = new Server() {
@Override
public void success(String data) {
System.out.print(data)
}
@Override
public void failure(int code) {
System.out.print(code)
}
};
server.start();
}
}

abstract class和interface在Java語言中都是用來進行抽象類定義.

使用abstract class的方式定義Demo抽象類的方式如下:

abstract class Demo {
abstract void method1();
abstract void method2();
…
}

使用interface的方式定義Demo抽象類的方式如下:

interface Demo {
void method1();
void method2();
…
}

在abstract class方式中,Demo可以有自己的資料成員,也可以有非abstarct的成員方法

而在interface方式的實現中,Demo只能夠有靜態的不能被修改的資料成員(也就是必須是static final的)

所有的成員方法都是abstract的。從某種意義上說,interface是一種特殊形式的abstract class。

考慮這樣一個例子,假設在我們的問題領域中有一個關於Door的抽象概念,該Door具有執行兩個動作open和close

此時我們可以通過abstract class或者interface來定義一個表示該抽象概念的型別,定義方式分別如下所示:

使用abstract class方式定義Door:

abstract class Door {
abstract void open();
abstract void close();
}

使用interface方式定義Door:

interface Door {
void open();
void close();
}

其他具體的Door型別可以extends使用abstract class方式定義的Door或者implements使用interface方式定義的Door。

看起來好像使用abstract class和interface沒有大的區別。

如果現在要求Door還要具有報警的功能。我們該如何設計針對該例子的類結構呢

解決方案一:

簡單的在Door的定義中增加一個alarm方法,如下:

abstract class Door {
abstract void open();
abstract void close();
abstract void alarm();
}

或者

interface Door {
void open();
void close();
void alarm();
}

那麼具有報警功能的AlarmDoor的定義方式如下:

class AlarmDoor extends Door {
void open() { … }
void close() { … }
void alarm() { … }
}

或者

class AlarmDoor implements Door {
void open() { … }
void close() { … }
void alarm() { … }
}

這種方法違反了面向物件設計中的一個核心原則ISP(Interface Segregation Priciple)

在Door的定義中把Door概念本身固有的行為方法和另外一個概念”報警器”的行為方法混在了一起。

這樣引起的一個問題是那些僅僅依賴於Door這個概念的模組會因為”報警器”這個概念的改變而改變,反之依然。

解決方案二:

既然open、close和alarm屬於兩個不同的概念,根據ISP原則應該把它們分別定義在代表這兩個概念的抽象類中。

定義方式有:這兩個概念都使用abstract class方式定義;

兩個概念都使用interface方式定義;一個概念使用abstract class方式定義,另一個概念使用interface方式定義。

方式定義。如下所示:

abstract class Door {
abstract void open();
abstract void close();
}
interface Alarm {
void alarm();
}
class AlarmDoor extends Door implements Alarm {
void open() { … }
void close() { … }
void alarm() { … }
}

這種實現方式基本上能夠明確的反映出我們對於問題領域的理解,正確的揭示我們的設計意圖。

其實abstract class表示的是”is a”關係, interface表示的是”like a”關係,大家在選擇時可以作為一個依據

abstract class和interface是Java語言中的兩種定義抽象類的方式,它們之間有很大的相似性。

但是對於它們的選擇卻又往往反映出對於問題領域中的概念本質的理解

對於設計意圖的反映是否正確、合理,因為它們表現了概念間的不同的關係(雖然都能夠實現需求的功能)。

這其實也是語言的一種的慣用法,希望讀者朋友能夠細細體會。