前言:spa
看到適配器我就立馬想到了學校的機房的插座爲何都是兩個腳的,而個人筆記本插頭是三個角的,這就致使了很尷尬的局面,接口不對我充不到電。。試想假如這個時候有一個插頭轉換器就行了,沒錯這裏的轉換器就是適配器,適配器模式也叫轉換器模式翻譯
適配器模式:設計
將一個類的接口轉換成客戶但願的另一個接口。適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做code
解決了什麼問題:對象
簡單來講,就是須要的東西就在眼前,但卻不能使用,而短期又沒法改造它,因而咱們就想辦法去適配它。好比插頭轉換器就是一種適配器,或者筆記本變壓器也是一種適配器,適配器模式只是一種迫不得已的一種補救方式,因此在系統設計的時候請忘記它blog
適配器模式結構圖是長這樣的(對象適配器)繼承
適配器模式結構圖是長這樣的(類適配器)接口
適配器的實現編譯
主要分爲兩種方式,一種是類適配器,而另外一種是對象適配器class
類適配器很是簡單,由於它面向的是目標是接口,爲何是接口,由於JAVA不支持多繼承,若是須要適配的方法是在一個類中的話,還好,可是若是是多個類就沒法玩了,因此須要的適配的方法必定是在接口中或者單個類中,言歸正轉,如今只要咱們寫一個適配器,其實就是寫一個類,這個適配器類只要繼原來的接口實現類,而後實現目標接口就寫完了
假設咱們有以下需求
//原來的目標類 public class A{ public void sayHi(){ System.out.print("HI"); } } //原來的客戶端 public class Client{ public static void main(String[] args){ A a=new A(); a.sayHi(); } } //如今需求變動,不能sayHi,須要用到另外一個接口的某個方法,而這個接口自己和目標類是沒有關係的,即實現類A和接口B是沒有關係的,這時候假如須要用到B接口中說你好的方法 有人會想,這不是很簡單嗎,直接在A類中實現B不就得了,想法是沒有錯的,可是這樣作至關於修改了源代碼,違背了咱們設計原則,只拓展不修改 因此要解決這個問題,能夠採用適配器模式來解決 剛剛說過了,類適配器的目標是接口 咱們須要新增一個適配器類來適配客戶端 public inteface B{ //須要適配的方法 你好(); } //而後咱們的本身寫的適配類 public class adapterA extends A implements B{ //這裏須要實現B中未實現的方法 你好(){ Systen.out.println("你好"); } } public class Client{ public static void main(String[] args){ B a=new adapterA(); a.sayHi();//既能夠調用原來的方法,由於繼承了原來的目標類A a.你好();//也能夠調用適配的方法,同時是沒有對A進行改動的也沒有對B接口改動 } }
下面講解對象適配器
這個對象適配器是針對剛剛假如須要適配多個類的方法給出的一種解決方案,採用的方式是組合(經過在內部包裝一個或多個Adaptee對象,把源接口轉換成目標接口)
例如這個類圖
翻譯者至關於一個適配器
public class Translator extends Player{ //組合須要適配的類 private ForeignCenter fc=new ForeignCenter(); 。。。 //覆蓋原來有方法,使用適配的類對象 public void Attack(){ fc.attack(); } public void Defense(){ fc.defense(); } }
還有一種冷門叫缺省適配器:
通常是爲了彌補接口過大所犯下的過錯
實現一個接口的子類,極可能出現不少方法是空着的狀況,由於你的接口設計的過大,致使接口中本來不應出現的方法出現了,結果如今子類根本用不上這個方法,但因爲JAVA語言規則的緣由,實現一個接口必須實現它的所有方法,因此咱們的子類不得不被迫寫一堆空方法在那,只爲了編譯經過。
假如咱們可以創造一個接口的默認實現類,它裏面都是一些默認的方法,固然這裏由於沒什麼可寫的就空着了,實際當中可能會加入一些默認狀況下的操做,好比若是方法返回結果整數,那麼咱們在缺省適配器中能夠默認返回個0。
只要繼承這個默認的適配器(DefaultPerson),而後覆蓋掉須要用到的的方法就好了,因爲適配器幫咱們提供了默認的實現,因此就不須要再寫了。可是這樣就浪費了一個繼承的位置
以上