适配器是干嘛的,为什么会有这个模式?
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
先看个例子,这个例子是关于皇位继承的一个小故事(不恰当的地方,大家理解就好)....
/** * 这个类(接口)的实例代表是帝的儿子(嫡子) */ interface Son{ void readZouzhe();//王子必须会阅读奏折(请原谅我这样命名。。。。) } /** * 嫡子(他们都有机会继承皇位) */ class Son1 implements Son{ @Override public void readZouzhe() { System.out.println("我不会阅读奏折,我一般阅读都是让大臣们帮忙看"); } } class Son2 implements Son{ @Override public void readZouzhe() { System.out.println("我会阅读一部分奏折"); } } /** * 庶子(没有继承皇帝的机会) */ class Son3{ public void readZouzheBySelf() { System.out.println("我很早之前就学会了(你别管我怎么学会的...)"); } } /** * 圣旨来了... */ class Decree{ //圣旨宣明,需要一位嫡子继承皇位; public void extendKing(Son son) { //... } } //庶子很优秀,但是嫡子还在,没啥机会继承皇位,这可咋办 /** * 这时候,军师来了,给庶子除了这么一个主意 * 1. 首先你需要改写一下族谱,把自己写进皇室族谱中(implements Son) * 2. 再者,作为正规的王子,你必须符合皇子的要求(会帮忙审批奏折),但是审批你早就已经会了,你按照你之前的方式就可以了 * 你已经符合继承皇位的要求了,去吧,好好治理天下。 */ class PackageSon3 extends Son3 implements Son{ @Override public void readZouzhe() { readZouzheBySelf(); } }
以上举例就是适配器模式的应用了,Son3是一个庶子,他没法继承皇位(圣旨中宣明,只能是Son的实例才可以继承),所以,如果他想继承皇位,他就必须找别的办法。就像一个类A,他有一个方法,这个方法只接收抽象类或接口B的实例,这个时候,如果想要让类A也可以作为参数可以传递进去,就得给类A包装一层,让它符合条件。
适配器还有另一个实现,其实这个实现和第一个实现,就相差一点点....
class PackageSon3 implements Son{ Son3 son3; public PackageSon3(Son3 son3) { this.son3 = son3; } @Override public void readZouzhe() { son3.readZouzheBySelf(); } }
将适配器类,改成这样,其实就是另一个实现了;第一个实现为类适配器模式,而第二个实现为对象适配器模式(委托方式);
我再举个额外的例子(这个例子是在我网上搜出来的,正好拿出来讲讲,加深印象)
public class InputStreamReader extends Reader { private final StreamDecoder sd; /** * Creates an InputStreamReader that uses the default charset. * * @param in An InputStream */ public InputStreamReader(InputStream in) { super(in); try { sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object } catch (UnsupportedEncodingException e) { // The default encoding should always be available throw new Error(e); } } }在InputStreamReader类中,可以很明显看出来,它是适配器类,而Reader是目标类,这里采用了对象适配器模式,StreamDecoder为inputStream转换过来的。