適配器就是一種適配中間件,它存在於不匹配的二者之間,用於連接二者,將不匹配變得匹配,簡單點理解就是平常所見的轉接頭,轉換器之類的存在。
適配器模式有兩種:類適配器、對象適配器、接口適配器
前二者在實現上有些許區別,作用一樣,第三個接口適配器差別較大。
1、類適配器模式:
原理:通過繼承來實現適配器功能。
當我們要訪問的接口A中沒有我們想要的方法 ,卻在另一個接口B中發現了合適的方法,我們又不能改變訪問接口A,在這種情況下,我們可以定義一個適配器p來進行中轉,這個適配器p要實現我們訪問的接口A,這樣我們就能繼續訪問當前接口A中的方法(雖然它目前不是我們的菜),然後再繼承接口B的實現類BB,這樣我們可以在適配器P中訪問接口B的方法了,這時我們在適配器P中的接口A方法中直接引用BB中的合適方法,這樣就完成了一個簡單的類適配器。
詳見下方實例:我們以ps2與usb的轉接爲例
2、對象適配器模式
原理:通過組合來實現適配器功能。
當我們要訪問的接口A中沒有我們想要的方法 ,卻在另一個接口B中發現了合適的方法,我們又不能改變訪問接口A,在這種情況下,我們可以定義一個適配器p來進行中轉,這個適配器p要實現我們訪問的接口A,這樣我們就能繼續訪問當前接口A中的方法(雖然它目前不是我們的菜),然後在適配器P中定義私有變量C(對象)(B接口指向變量名),再定義一個帶參數的構造器用來爲對象C賦值,再在A接口的方法實現中使用對象C調用其來源於B接口的方法。
詳見下方實例:我們仍然以ps2與usb的轉接爲例
ps2接口:Ps2
public interface Ps2 {
void ps2();
}
USB接口:Usb
package com.Geeksun.adapter;
public interface Usb {
void usb();
}
USB接口實現類:Usber
package com.Geeksun.adapter;
public class Usber implements Usb{
@Override
public void usb() {
System.out.println("I'm usb.");
}
}
類適配器模式
適配器:Adapter
package com.Geeksun.adapter;
public class Adapter extends Usber implements Ps2 {
@Override
public void ps2() {
usb();
}
}
對象適配器模式
適配器:Adapter2
package com.Geeksun.adapter;
public class Adapter2 implements Ps2 {
Usb usb;
Adapter2(Usb usb){
this.usb = usb;
}
@Override
public void ps2() {
usb.usb();
}
}
測試方法:Client
package com.Geeksun.adapter;
public class Client {
public static void main(String[] args) {
Adapter adapter = new Adapter();
adapter.ps2();
Usb usb = new Usber();
Adapter2 adapter2 = new Adapter2(usb);
adapter2.ps2();
}
}
3、接口適配器模式
原理:通過抽象類來實現適配,這種適配稍別於上面所述的適配。
當存在這樣一個接口,其中定義了N多的方法,而我們現在卻只想使用其中的一個到幾個方法,如果我們直接實現接口,那麼我們要對所有的方法進行實現,哪怕我們僅僅是對不需要的方法進行置空(只寫一對大括號,不做具體方法實現)也會導致這個類變得臃腫,調用也不方便,這時我們可以使用一個抽象類作爲中間件,即適配器,用這個抽象類實現接口,而在抽象類中所有的方法都進行置空,那麼我們在創建抽象類的繼承類,而且重寫我們需要使用的那幾個方法即可。
目標接口:A
public interface A {
void a();
void b();
void c();
void d();
void e();
void f();
}
適配器:Adapter
public abstract class Adapter implements A {
public void a(){}
public void b(){}
public void c(){}
public void d(){}
public void e(){}
public void f(){}
}
實現類:Ashili
public class Ashili extends Adapter {
public void a(){
System.out.println("實現A方法被調用");
}
public void d(){
System.out.println("實現d方法被調用");
}
}
測試類:Clienter
public class Clienter {
public static void main(String[] args) {
A a = new Ashili();
a.a();
a.d();
}
}
4、適配器模式應用場景
類適配器與對象適配器的使用場景一致,僅僅是實現手段稍有區別,二者主要用於如下場景:
(1)想要使用一個已經存在的類,但是它卻不符合現有的接口規範,導致無法直接去訪問,這時創建一個適配器就能間接去訪問這個類中的方法。
(2)我們有一個類,想將其設計爲可重用的類(可被多處訪問),我們可以創建適配器來將這個類來適配其他沒有提供合適接口的類。
以上兩個場景其實就是從兩個角度來描述一類問題,那就是要訪問的方法不在合適的接口裏,一個從接口出發(被訪問),一個從訪問出發(主動訪問)。
接口適配器使用場景:
(1)想要使用接口中的某個或某些方法,但是接口中有太多方法,我們要使用時必須實現接口並實現其中的所有方法,可以使用抽象類來實現接口,並不對方法進行實現(僅置空),然後我們再繼承這個抽象類來通過重寫想用的方法的方式來實現。這個抽象類就是適配器。