zoukankan      html  css  js  c++  java
  • [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接口的对象。

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

  • 相关阅读:
    【51nod 1331】狭窄的通道
    【noip 2016】提高组
    【noip 2016】普及组
    【bzoj 4764】弹飞大爷
    线筛
    高斯消元
    网络流
    平衡二叉树 treap

    双向广搜
  • 原文地址:https://www.cnblogs.com/YFEYI/p/12178798.html
Copyright © 2011-2022 走看看