[Thiinking in Java]自闭学习之路(三)接口下

前言-

本文是为个人学习做的整理性质的笔记,肯定带有许多不妥的地方,仅供参考。

(第九章·接口 《Thinking in Java》)

  接口不仅仅只是一种更纯粹形式的抽象类

正文-

  接口不仅仅只是一种更纯粹形式的抽象类,他的目标比这还要高。比如说“完全解耦”和“多重继承

  首先是完全解耦,这个你与要对耦合有一定的了解,只要一个方法操作的是类而非接口,那么你就只能使用这个类及其子类。

  现在我们有个Processor类,它包含name()方法和process()方法。Splitter方法继承Processor并重写process()方法,实现按照空格切分字符串的功能。

  在Apply中,Apply.process()方法可以接受任何类型的Processor(只要它继承自Processor),并将其运用到一个Object对象上,然后打印结果。

class Processor {
    public String name() {
        return getClass().getSimpleName();
    }
    Object process(Object input) {
        return input;
    }
}

class Splitter extends Processor{
    @Override
    Object process(Object input) {
        // TODO 自动生成的方法存根
        return Arrays.toString(((String)input).split(" "));
    }
}

public class Apply{
    public static void process(Processor p,Object s) {
        System.out.println("Using Processor "+p.name());
        System.out.println(p.process(s));
    }
    public static String s="i love you baby";
    public static void main(String[] args) {
        process(new Splitter(),s);
    }
}
继承调用

  ※像例子这样的,创建一个能够根据所传参数对象的不同而是用不同行为的方法,被称为策略设计模式。这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分。

  ※策略就是传进去的参数对象,它包含要执行的代码。这里Processor就是一个策略。

  不过这些并不是重点,Splitter的实现也不是重点。

  记住Processor的样子!才是重点!

接下来是另一组类

public class Waveform {//    波形类
    private static long count;
    private final  long id=count++;
    public String toString(){
        return "Waveform "+id;
    }
}

class Filter{//    适配器类
    public String name() {
        return getClass().getSimpleName();
    }
    Object process(Waveform input) {
        return input;
    }
}

class BandPass extends Filter{// 滤波器类
    double  lowCutoff,hightCutoff;
    public BandPass(double  lowCutoff,double hightCutoff) {
        // TODO 自动生成的构造函数存根
        this.lowCutoff=lowCutoff;
        this.hightCutoff=hightCutoff;
    }
    @Override
        Object process(Waveform input) {
            // TODO 自动生成的方法存根
            return input;
        }
}
另一组类

  观察Filter类与Processor,她两具有相同的接口元素。如果在mian方法中尝试调用static 的Apply.process(p,s);时,编译器会提示Apply的process(p,s)方法不适用。因为你在将一个方法应用于不在此继承结构中的某个类中。

  ※此时Apply.process()就与Processor之间的耦合过紧。

使用接口可以很大程度上的放宽这种耦合,现在我们将Processor改成接口类型

public interface iProcessor {
    String name();
    Object process(Object input);
}
public class StringProcessor implements iProcessor {
    public static String s="i love you baby";
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        NewApply.process(new Splitter(),s);
    }

    @Override
    public String name() {
        // TODO 自动生成的方法存根
        return getClass().getSimpleName();
    }

    @Override
    public Object process(Object input) {
        // TODO 自动生成的方法存根
        return input;
    }

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

class NewSplitter extends StringProcessor{
    @Override
    public Object process(Object input) {
        // TODO 自动生成的方法存根
        return Arrays.toString(((String)input).split(" "));
    }
}
View Code

现在Processor被接口化为iProcessor,怎样适用于Wavefform呢?

那就可以采用适配器设计模式。通过适配器Adapter接受你所拥有的接口(类型),并产生你所需要的的接口(类型)。

public class FilterAdapter implements iProcessor {
    Filter f;
    public FilterAdapter(Filter f) {
        // TODO 自动生成的构造函数存根
        this.f=f;    //    将刚刚的fiter传进来做适配
    }
    @Override
    public String name() {
        // TODO 自动生成的方法存根
        return f.name();
    }

    @Override
    public Object process(Object input) {
        // TODO 自动生成的方法存根
        return f.process((Waveform)input);
    }

}
Adapter
public class FilterProcessor {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Waveform w=new Waveform();
        NewApply.process(new FilterAdapter(new BandPass(3.0, 4.0)), w);
    }

}
调用

就这样Adapter接受了你原来拥有的Filter类型,并产生了一个你急需的iProcessor接口的对象。

※虽然适配器看起来很实用,但是尽量少使用她。当你过多使用适配器转换的时候,就应该反思一下是不是设计出了什么问题。

相关推荐