thinkinginjava學習筆記08_接口

抽象類和抽象方法

抽象方法是指沒有具體實現的方法,僅僅有方法的聲明和沒有方法體;使用abstract關鍵字定義一個抽象方法;包含抽象方法的類成爲抽象類,若是一個類中包含抽象方法則必須使用abstract來限定該類爲抽象類;抽象類不能實例化對象,抽象類的子類必須對全部的抽象方法提供方法定義,不然仍然是抽象類,且必須用abstract來限定;java

接口

接口是一個徹底抽象的類,沒有提供任何具體的實現,只提供了具體的方法形式(方法名、參數列表、返回值);因爲類是經過接口和外部通訊,接口被用來創建類和類之間的協議(protocol);使用interface代替class定義一個接口,在接口中,全部的方法都是public的,就算不添加public,也會自動成爲public,不然這將限制接口的意義;git

接口中除了抽象方法,還能夠包含域,可是這些域將隱式地成爲static和final的(常量,用大寫字母表示)而且不能夠是空final,能夠被常量表達式初始化這些域並非接口的一部分,而是存儲在該接口的靜態存儲區域內;github

讓一個類遵循某個(或者某組)特定的接口,須要使用implements關鍵字,表示該類使用的接口的樣子,以及該類將對接口中的方法作具體實現;設計模式

示例代碼中,Wind、Percussion、Stringed都使用了Instrument接口,表名這四個類(接口)都具備相同的行爲;從Wind派生出兩個子類:Brass、Woodwind,這兩個子類也能夠經過向上轉型,使用該接口;函數

徹底解耦

接口相對於繼承的意義是:若是方法操做的是類,那麼該方法只能使用這個類及其子類,不然將會出錯;而經過方法操做一個接口,則沒有該限制,只要知足該接口的類均可以被調用;this

建立一個可以根據所傳遞的參數對象的不一樣而具備不一樣行爲的方法,稱爲策略設計模式;如:spa

publicclass Apply {設計

    public static void process(Processor p, Object s){代理

        println("Using Processor " + p.name());orm

        println(p.process(s));

    }

}

 

Apply.process()方法接收一個Processor對象,並將其應用到Object對象上;根據不一樣Processor接口的實現(策略),該方法對Object能夠有不一樣的行爲;

當Processor是一個類時,Apply.process()方法和Processor之間是緊耦合的,只能接收該類或者其子類的對象,當一個具備相同接口的其餘類使用該方法時,複用會被禁止;而當Processor是一個接口時,耦合就會鬆動,只要是相同接口的類的對象均可以接收;

若是已有一個類Filter,要將其改變成Processor接口的類,則須要使用到適配器:

class FilterAdapter implements Processor{

    Filter filter;

    FilterAdapter(Filter filter){

        this.filter = filter;

    }

    public String name() {

        return filter.name();

    }

    public Object process(Object input) {

        return filter.process((Waveform)input);

    }

}

 

該類使用了Processor接口,並接受一個Filter對象,用代理的方式,將Filter對象像Processor接口適配;

見:示例代碼,其中依賴的部分見相同路徑下的各個類文件;

多重繼承

示例代碼中,Hero繼承了基類ActionCharacter,而且繼承了三個接口:CanSwim、CanFight、CanFly;此時,具體基類必須放在前面,而接口放到後面而且用逗號隔開;

在Adventure中,實現了四個方法,而且傳入不一樣的接口和類,而Hero對象能夠被傳遞到這些接口或者類中的任何一個;

接口能夠經過繼承其餘的接口來進行擴展,使用extends進行擴展,而且若是繼承多個接口,則使用逗號隔開(extends用於類時,只適用於單一類);

在使用多重繼承時,應該避免多個不一樣接口中存在相同的方法名,這樣作會形成代碼可讀性的混亂;

經過多重繼承,能夠對適配器進行功能擴展,使其能夠在任何現有類之上添加接口,讓現有類適配成某個方法;

接口與工廠

如在示例代碼中,使用工廠方法,避免在使用某一個Service類的對象時,調用特定的構造方法,而是使用一個特定接口的工廠方法,並在其中實現構造函數的調用,此時,只要對該接口進行實現便可;

有關工廠方法的討論在Effective Java中也提到,目前只有一個主觀認識,須要在使用中加深;

相關文章
相關標籤/搜索