細說Java的接口(一)

君子不器。(君子不能像器具一般,只有一種用途。)


——《論語》


    這一章討論
Java編程中的另外一個重要概念和技術——接口。首先闡述什麼是接口,它與類和抽象類的不同,以及使用接口的目的。本章通過實例詳細討論怎樣編寫接口和實現接口,怎樣利用接口實現多重繼承,接口本身的繼承性,以及接口的具體應用實例。

9.1  概述

類似於硬件接口設計,如計算機母板上的各種接口,Java語言中的接口,應用高度抽象概念和編程形式,以及應用時必須完善接口的要求,達到對象通過接口與外部世界的    聯繫。

9.1.1  接口和類

如果說類對它所代表的對象的形態和行爲提供了具體的運算和操作代碼,接口只是對要實現接口的所有類提出了協議(protocol)。這些協議是類和接口的通訊和對話管道,以靜態常量和方法簽名的形式,使不同的類之間建立起一個共享體制,這就像CPU的管腳對準其接口的插腳一樣。這看起來似乎對類很寬容,實際上對類提出了管理和組織機制。對類的行爲,提出了政策性的宏觀控制。

 

public interface Plugable {
    static final String componentID = "CPU";        //可選項
    void plugin(argumentList);                      //可選項
}

 

即接口中只規定靜態常量,方法簽名以及返回類型,而無具體操作代碼。具體的方法行爲由繼承這個接口的類來實現。可以看到,一個接口有可能是隻有接口名的空接口。
接口具有可繼承性。如同類一樣,接口中的靜態常量(如果有,只能是公共靜態常量)和方法可以被實現它的類所繼承。所以,接口技術爲在Java中實現多重繼承(multiple inheritance)提供了可能性。即一個子類可以繼承多個直接超類。在Java編程中,更確切地說,應該是一個子類可以繼承一個直接超類和多個接口(參見圖7.4)。即:

 

public class SubClass extends SuperClass implements Interface1, Interface2, InterfaceN {
    ...
}

 

我們稱這種多重繼承爲間接多重繼承。因爲子類僅繼承了接口中對方法編寫的協議規範,還必須編寫完善這些方法的具體代碼。
如果說子類繼承超類是“is a”,即“是”的關係,類和支持類之間是“has a”,即“有”的關係,或稱“組合”,那麼類和接口則是“like a”,即“像是”的關係。接口表示,所有實現了我這個接口的類都具有我規定的協議,即“看起來都像我”,確切地說,“看起來都像我的簽名”。因爲完善這個接口的類必須按照簽名和返回類型編寫具體代碼。當然,類知道應該調用哪些方法纔可實現繼承過來的接口功能。作一個比喻,繼承好比“給予財富”,組合好比“你擁有我”,而接口則是“你中有我”。
接口技術有助於實現類之間的“鬆散關聯”關係(loose coupling,也稱鬆散耦合)。“鬆散關聯”闡述瞭如下兩個面向對象編程中的重要原則:
1.         儘可能地使類獨立存在,“自給自足”(tied cohesion)。
2.         如果類之間有依賴關係,儘可能實現鬆散關聯(loose coupling)。
接口以協議的形式建立了類之間的鬆散關係。體現了行爲規範和行爲實現的分離。使接口,這個特殊類的設計,上升到更抽象的高度。

9.1.2  接口和抽象

       接口的本質是抽象,是抽象類完全抽象化的體現。所以有些文獻中稱接口爲“純抽象類”。如果說在抽象類中,還允許完善了的方法和實例變量存在的話,在接口中,只允許有代表協議的方法簽名和其返回類型,以及靜態常量。
抽象類中,以抽象方法作爲接口,成爲子類實現多態的協議規範。而接口將類的全部內容昇華爲抽象,成爲子類按照指定行爲規範,遵循協議約定來實現接口功能的準則。實際上,接口對抽象類提供了行爲規範和行爲實現分離的絕好機會,使得改寫後的抽象類更加符合“自給自足”和“鬆散耦合”的設計原則。如一個抽象類:

 

public abstract someAbstractClass {
    ...
    public abstract void someMethod();
}

 

分離成爲一個接口和一個完善接口的類:

 

public interface SomeInterface {
    public abstract void someMethod();
}

 

以及:

 

public class SomeClass implements someInterface {
    ...
    public void someMethod() {...}
}

 

這樣做的好處是:
l  使協議成爲獨立的接口。
l  使成爲接口的協議具有更廣泛的代表性和應用空間。
l  使抽象類從抽象中分離出來,使其不再包括抽象方法,因而具有創建對象的功能(注意抽象類不能夠創建對象)。

9.1.3  步入接口

接口的語法格式爲:

 

public interface InterfaceName {
    public static final varType CONSTANT_NAME = value;      //可選項
    public abstract returnType methodName(argumentList);    //可選項
}

 

其中:
interface——關鍵字。用來定義一個接口。
varType——任何基本變量類型。接口中的變量必須是靜態常量。publicstaticfinal關鍵字可以省略。一個接口可以沒有靜態常量。
returnType——返回類型。可以是任何變量類型或者對象,或void
argumentList——包括參數類型和參數名。多個參數間用逗號分隔。接口中所有的方法必須是抽象方法。publicabstract關鍵字可以省略。一個接口可以沒有方法聲明。
所以接口的簡化語法格式爲:

 

public interface Interface Name {
varType CONSTANT_NAME value;                //可選項
return Type method Name (argument List);    //可選項
}

 

以下利用這個簡化格式討論接口技術和編程。
1:編寫一個Printable接口。

 

public interface Printable {
    void print();
}

 

這個接口規定凡是實現這個接口的類必須有print()方法,它的返回類型是void的。
2:編寫一個只有靜態常量的接口。

 

public interface DepartmentCode {
    int ADMINI = 1;
    int FINANCE = 2;
    int MARKETING = 3
    int SERVICES = 4;
}

 

這個接口只定義了靜態常量。完善它的所有類必須遵循這些部門代碼的規定。
3:編寫一個對所有圖形組件規定位置協議的接口。

 

public interface Positionable {
    short X0 = 0;
    short Y0 = 0;
    short getX();
    short getY();
    void setX(short x);
    void setY(short y);
}

 

這個接口規定了所有圖形組件的原始座標,以及必須具有的方法協議。
4APICloneable接口。

 

public interface Cloneable {
}

 

這是Java API的空接口。它建議完善它的類應該覆蓋Object.Clone()方法。我們將在以後的小節討論如何完善這個接口。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章