天天看點

Java 抽象類和接口,看這一篇就夠了(2)

04、 接口在應用中常見的三種模式

在程式設計領域,好的設計模式能夠讓我們的代碼事半功倍。在使用接口的時候,經常會用到三種模式,分别是政策模式、擴充卡模式和工廠模式。

1)政策模式

政策模式的思想是,針對一組算法,将每一種算法封裝到具有共同接口的實作類中,接口的設計者可以在不影響調用者的情況下對算法做出改變。示例如下:

// 接口:教練
interface Coach {
    // 方法:防守
    void defend();
}

// 何塞·穆裡尼奧
class Hesai implements Coach {

    @Override
    public void defend() {
        System.out.println("防守赢得冠軍");
    }
}

// 德普·瓜迪奧拉
class Guatu implements Coach {

    @Override
    public void defend() {
        System.out.println("進攻就是最好的防守");
    }
}

public class Demo {
    // 參數為接口
    public static void defend(Coach coach) {
        coach.defend();
    }
    
    public static void main(String[] args) {
        // 為同一個方法傳遞不同的對象
        defend(new Hesai());
        defend(new Guatu());
    }
}

      

Demo.defend() 方法可以接受不同風格的 Coach,并根據所傳遞的參數對象的不同而産生不同的行為,這被稱為“政策模式”。

2)擴充卡模式

擴充卡模式的思想是,針對調用者的需求對原有的接口進行轉接。生活當中最常見的擴充卡就是HDMI(英語:High Definition Multimedia Interface,中文:高清多媒體接口)線,可以同時發送音頻和視訊信号。擴充卡模式的示例如下:

interface Coach {
    void defend();
    void attack();
}

// 抽象類實作接口,并置空方法
abstract class AdapterCoach implements Coach {
    public void defend() {};
    public void attack() {};
}

// 新類繼承擴充卡
class Hesai extends AdapterCoach {
    public void defend() {
        System.out.println("防守赢得冠軍");
    }
}

public class Demo {
    public static void main(String[] args) {
        Coach coach = new Hesai();
        coach.defend();
    }
}

      

Coach 接口中定義了兩個方法(defend() 和 attack()),如果類直接實作該接口的話,就需要對兩個方法進行實作。

如果我們隻需要對其中一個方法進行實作的話,就可以使用一個抽象類作為中間件,即擴充卡(AdapterCoach),用這個抽象類實作接口,并對抽象類中的方法置空(方法體隻有一對花括号),這時候,新類就可以繞過接口,繼承抽象類,我們就可以隻對需要的方法進行覆寫,而不是接口中的所有方法。

3)工廠模式

所謂的工廠模式了解起來也不難,就是什麼工廠生産什麼,比如說寶馬工廠生産寶馬,奔馳工廠生産奔馳,A 級學院畢業 A 級教練,C 級學院畢業 C 級教練。示例如下:

// 教練
interface Coach {
    void command();
}

// 教練學院
interface CoachFactory {
    Coach createCoach();
}

// A級教練
class ACoach implements Coach {

    @Override
    public void command() {
        System.out.println("我是A級證書教練");
    }
    
}

// A級教練學院
class ACoachFactory implements CoachFactory {

    @Override
    public Coach createCoach() {
        return new ACoach();
    }
    
}

// C級教練
class CCoach implements Coach {

    @Override
    public void command() {
        System.out.println("我是C級證書教練");
    }
    
}

// C級教練學院
class CCoachFactory implements CoachFactory {

    @Override
    public Coach createCoach() {
        return new CCoach();
    }
    
}

public class Demo {
    public static void create(CoachFactory factory) {
        factory.createCoach().command();
    }
    
    public static void main(String[] args) {
        // 對于一支球隊來說,需要什麼樣的教練就去找什麼樣的學院
        // 學院會介紹球隊對應水準的教練。
        create(new ACoachFactory());
        create(new CCoachFactory());
    }
}

      

有兩個接口,一個是 Coach(教練),可以 command()(指揮球隊);另外一個是 CoachFactory(教練學院),能 createCoach()(教出一名優秀的教練)。然後 ACoach 類實作 Coach 接口,ACoachFactory 類實作 CoachFactory 接口;CCoach 類實作 Coach 接口,CCoachFactory 類實作 CoachFactory 接口。當需要 A 級教練時,就去找 A 級教練學院;當需要 C 級教練時,就去找 C 級教練學院。

依次類推,我們還可以用 BCoach 類實作 Coach 接口,BCoachFactory 類實作 CoachFactory 接口,進而不斷地豐富教練的梯隊。

05、 總結

盡管接口使得抽象更進一步,但任何抽象性都應該根據真正的需求而産生,是以恰當的原則是優先選擇類而不是接口,隻有在真正需要接口的時候再重構代碼。