《Thanking in Java》9. 接口

9.1 抽象類和抽象方法

包含抽象方法的類叫做抽象類,如果一個(gè)類包含一個(gè)或多個(gè)抽象方法,該類必須被限定為抽象的入宦。

如果從一個(gè)抽象類繼承,并想創(chuàng)建該新類的對(duì)象室琢,那么就必須為基類中的所有抽象方法提供方法定義乾闰。

創(chuàng)建抽象類和抽象方法非常有用,因?yàn)樗麄兛梢允诡惖某橄笮悦鞔_起來研乒,并告訴用戶和編譯器打算怎樣使用他們汹忠。抽象類還是很有用的重構(gòu)工具淋硝,因?yàn)樗麄兯频奈覀兛梢院苋菀椎貙⒐卜椒ㄑ刂^承層次結(jié)構(gòu)向上移動(dòng)雹熬。

9.2 接口

Interface不僅僅是一個(gè)極度抽象的類,因?yàn)樗试S人們通過創(chuàng)建一個(gè)能夠向上轉(zhuǎn)型為多種基類的類型谣膳,來實(shí)現(xiàn)某種類似多重繼承變種的特性竿报。

接口也可以包含域。但是這些域隱式地是static和final的继谚。
只要一個(gè)方法操作的是類而非接口烈菌,那么你就只能使用這個(gè)類及其子類。接口可以在很大程度上放寬這種限制,因此芽世,它使得我們可以編寫可復(fù)用性更好的代碼挚赊。

創(chuàng)建一個(gè)能夠根據(jù)所傳遞的參數(shù)對(duì)象的不同而具有不同行為的方法,被稱為“策略設(shè)計(jì)模式”
適配器模式實(shí)例:

package chapter9;

/**
 * Created by Blue on 2017/8/24.
 * 9.3 適配器模式
 */
interface Processor1 {
    String name();

    Object process(Object input);
}

class Waveform {
    private static long counter;
    private final long id = counter++;

    public String toString() {
        return "Waveform " + id;
    }
}

class Filter {
    public String name() {
        return getClass().getSimpleName();
    }

    public Waveform process(Waveform input) {
        return input;
    }
}

class LowPass extends Filter{
    double cutoff;
    public LowPass(double cutoff) {
        this.cutoff = cutoff;
    }
    public Waveform process(Waveform input) {
        return input;
    }
}
class HighPass extends Filter{
    double cutoff;
    public HighPass(double cutoff) {
        this.cutoff = cutoff;
    }
    public Waveform process(Waveform input) {
        return input;
    }
}
class BandPass extends Filter{
    double lowCutoff, highCutoff;
    public BandPass(double lowCut, double highCut) {
        this.lowCutoff = lowCut;
        this.highCutoff = highCut;
    }
    public Waveform process(Waveform input) {
        return input;
    }
}

class Apply1{
    public static void process(Processor1 p, Object s) {
        System.out.println("Using Processor " + p.name());
        System.out.println(p.process(s));
    }
}

class FilterAdapter implements Processor1 {

    Filter filter;

    public FilterAdapter(Filter filter) {
        this.filter = filter;
    }

    public String name() {
        return filter.name();
    }

    public Waveform process(Object input) {
        return filter.process((Waveform) input);
    }
}

public class FilterProcessor {
    public static void main(String[] args) {
        Waveform w = new Waveform();
        Apply1.process(new FilterAdapter(new LowPass(1.0)), w);
        Apply1.process(new FilterAdapter(new HighPass(2.0)), w);
        Apply1.process(new FilterAdapter(new BandPass(3.0, 4.0)),w);
    }
}

9.4 java中的多重繼承

可以繼承任意多個(gè)接口济瓢,并可以向上轉(zhuǎn)型為每個(gè)接口荠割,因?yàn)槊總€(gè)接口都是一個(gè)獨(dú)立類型。

如果知道某事物應(yīng)該成為一個(gè)基類旺矾,那么第一選擇應(yīng)該是使它成為一個(gè)接口蔑鹦。

interface Fly {
    void canFly();
}

interface Eat extends Fly {
    void canEat();
}

interface Drink extends Fly {
    void canDrink();
}

interface DoAll extends Fly, Eat, Drink {
    void canDoAll();
}

class Animal {
    public void canDoAll() {
        
    }
}

class Bird extends Animal implements DoAll {

    public void canFly() {

    }

    public void canEat() {

    }

    public void canDrink() {

    }
}

9.5 通過繼承來擴(kuò)展接口

一般情況下,只可以將extends用于單一類箕宙,但是可以引用多個(gè)基類接口嚎朽。

打算組合的不同接口中使用相同的方法名通常會(huì)造成代碼可讀性的混亂,盡量避免這種情況柬帕。

9.6 適配接口

接口最吸引人的原因之一就是允許同一個(gè)接口具有多個(gè)不同的具體實(shí)現(xiàn)哟忍。在簡單的情況下,它的體現(xiàn)通常是一個(gè)接受接口類型的方法陷寝,而該接口的實(shí)現(xiàn)和向該方法傳遞的對(duì)象則取決于方法的使用者魁索。

讓方法接受接口類型,是一種讓任何類都可以對(duì)該方法進(jìn)行適配的方式盼铁。這就是使用接口而不是類的強(qiáng)大之處粗蔚。

9.7 接口中的域

接口中的任何域都是static和final的。

9.8 嵌套接口

//: interfaces/nesting/NestingInterfaces.java
package interfaces.nesting;

class A {
  interface B {
    void f();
  }
  public class BImp implements B {
    public void f() {}
  }
  private class BImp2 implements B {
    public void f() {}
  }
  public interface C {
    void f();
  }
  class CImp implements C {
    public void f() {}
  } 
  private class CImp2 implements C {
    public void f() {}
  }
  private interface D {
    void f();
  }
  private class DImp implements D {
    public void f() {}
  }
  public class DImp2 implements D {
    public void f() {}
  }
  public D getD() { return new DImp2(); }
  private D dRef;
  public void receiveD(D d) {
    dRef = d;
    dRef.f();
  }
}   

interface E {
  interface G {
    void f();
  }
  // Redundant "public":
  public interface H {
    void f();
  }
  void g();
  // Cannot be private within an interface:
  //! private interface I {}
}   

public class NestingInterfaces {
  public class BImp implements A.B {
    public void f() {}
  }
  class CImp implements A.C {
    public void f() {}
  }
  // Cannot implement a private interface except
  // within that interface's defining class:
  //! class DImp implements A.D {
  //!  public void f() {}
  //! }
  class EImp implements E {
    public void g() {}
  }
  class EGImp implements E.G {
    public void f() {}
  }
  class EImp2 implements E {
    public void g() {}
    class EG implements E.G {
      public void f() {}
    }
  } 
  public static void main(String[] args) {
    A a = new A();
    // Can't access A.D:
    //! A.D ad = a.getD();
    // Doesn't return anything but A.D:
    //! A.DImp2 di2 = a.getD();
    // Cannot access a member of the interface:
    //! a.getD().f();
    // Only another A can do anything with getD():
    A a2 = new A();
    a2.receiveD(a.getD());
  }
} ///:~

接口也可以在嵌套接口中被實(shí)現(xiàn)為private饶火,它可以強(qiáng)制該接口中的方法定義不要添加任何類型信息鹏控,也就是說,不允許向上轉(zhuǎn)型肤寝。
在public方法中獲取private接口對(duì)象当辐,其返回值只能交給有權(quán)使用它的對(duì)象。
嵌套在另一個(gè)接口中的接口自動(dòng)就是public的鲤看,而不能聲明為private的缘揪。
private接口不能在定義它的類之外被實(shí)現(xiàn)。

9.9 接口與工廠

接口是實(shí)現(xiàn)多重繼承的途徑义桂,而生成遵循某個(gè)接口的對(duì)象的典型方法就是工廠方法設(shè)計(jì)模式找筝。這與直接條用構(gòu)造器不同,我們?cè)诠S對(duì)象上調(diào)用的是創(chuàng)建方法慷吊,而該工廠對(duì)象將生成接口的某個(gè)實(shí)現(xiàn)的對(duì)象袖裕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市溉瓶,隨后出現(xiàn)的幾起案子急鳄,更是在濱河造成了極大的恐慌谤民,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疾宏,死亡現(xiàn)場離奇詭異张足,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坎藐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門兢榨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人顺饮,你說我怎么就攤上這事吵聪。” “怎么了兼雄?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵吟逝,是天一觀的道長。 經(jīng)常有香客問我赦肋,道長块攒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任佃乘,我火速辦了婚禮囱井,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘趣避。我一直安慰自己庞呕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布程帕。 她就那樣靜靜地躺著住练,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愁拭。 梳的紋絲不亂的頭發(fā)上讲逛,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音岭埠,去河邊找鬼盏混。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惜论,可吹牛的內(nèi)容都是我干的许赃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼来涨,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼图焰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹦掐,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤技羔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卧抗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藤滥,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年社裆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拙绊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泳秀,死狀恐怖标沪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嗜傅,我是刑警寧澤金句,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站吕嘀,受9級(jí)特大地震影響违寞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偶房,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一趁曼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棕洋,春花似錦挡闰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至庆杜,卻和暖如春射众,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晃财。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工叨橱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人断盛。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓罗洗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钢猛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伙菜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法命迈,內(nèi)部類的語法贩绕,繼承相關(guān)的語法火的,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評(píng)論 18 399
  • (一)Java部分 1淑倾、列舉出JAVA中6個(gè)比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,104評(píng)論 0 62
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理馏鹤,服務(wù)發(fā)現(xiàn),斷路器娇哆,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡單原理和應(yīng)用湃累。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 4,591評(píng)論 1 114
  • 三月份開始畫彩鉛的,斷斷續(xù)續(xù)差不多快一個(gè)月了碍讨,一直想著有機(jī)會(huì)也寫個(gè)教程治力,但是一直拖拖拉拉。今天就只好逼自己一...
    懵橙閱讀 1,967評(píng)論 7 4