JavaSE基础知识(十九)--Java接口之适配接口

Java SE 是什么,包括哪些内容(十九)?

本文内容参考自Java8标准
再次感谢Java编程思想对本文的启发!
接口最吸引人的原因之一就是允许同一个接口具有多个不同的实现(就是每个实现接口的类都可以给这个接口的所有方法以不同的实现,而不用去修改主体框架的代码),在简单的情况中,它的体现形式通常是只规定一个接受接口类型的方法(public void f(xxx接口类型 s)),而该接口的实现和向该方法传递的实际对象类型则取决于方法的使用者。
因此,接口的一种常见用法就是"策略模式",此时你编写一个执行某些操作的方法,而该方法将接受一个同样是你指定的接口类型,其实,你这就是声明了:“你可以用任何你想要的对象来调用我的方法,只要你实现我规定的接口类型”,这使得你的方法更加灵活、通用、并更具可复用性。
举例:
Java SE5的类Scanner的构造方法接受的就是一个Readable接口,你会发现Readable接口没有用作Java标准类库中其他任何方法的参数,它是单独为类Scanner创建的,以使得类Scanner不必将其形式参数限制为某个特定的类。通过这种方式,Scanner可以作用于更多的类型。如果你创建了一个新的类,并且想让Scanner可以作用于它,那么你就应该让这个类实现接口Readable。

源码截图示例(Scanner构造方法中接受接口Readable类型的参数):
构造方法一:
JavaSE基础知识(十九)--Java接口之适配接口_第1张图片
构造方法二:
JavaSE基础知识(十九)--Java接口之适配接口_第2张图片
Java API文档截图:
JavaSE基础知识(十九)--Java接口之适配接口_第3张图片
Readable代表的是指定的源,假设你有一个类,代表了文件或者是字符串或者其他的源等等,你就可以让这个类实现接口Readable,然后类Scanner就能作用你这个源,你就可以使用它提供了多种方法。
代码示例:

// 适配接口
   //类RandomWords实现接口Readable
   public class RandomWords implements Readable{
      //创建随机类Random的对象
      private static Random rand = new Random(43);
      //static final的char数组类型capitals
      //方法toCharArray()是类String的方法
      //作用是将字符串转换为字符数组
      //这里将字符串"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      //转换为了字符数组
      private static final char[] capitals = 
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
      //同上
      private static final char[] lowers = 
      "abcdefghijklmnopqrstuvwxyz".toCharArray();
      //同上
      private static final char[] vowels = 
      "aeiou".toCharArray();
      //int类型的类变量count,起一个计数器的作用
      private int count;
      //构造方法,带一个int类型的形式参数i
      public RandomWords(int count){
         //初始化类变量i
         this.count = count;
      }
      //方法read,这是接口Readable中规定必须实现的方法
      //带一个CharBuffer类型的形式参数cb
      public int read(CharBuffer cb){
         //if判断,如果表达式count--的值为0,那么就返回
         //-1,实际上,在每次调用方法read的时候,都需要判断
         //count的值是多少,如果为0,就表示不用读了。
         //count--中"--"的意思是保证下次调用read方法的时候
         //count的值比这次少1.
         //couunt--表达式的值和count的值是等价的,只不过count--
         //能自减。
         if(count-- == 0){
            //返回-1,表示计数器count为0了。
            return -1;
         }
         //如果没有读到末尾就继续...
         //cb调用方法append()进行字符拼接.
         //rand.nextInt()表示随机读取一个整数
         //capitals.length表示字符数组capitals的长度
         //那么rand.nextInt(capitals.length)表示
         //在0-capitals.length的值之内随机选择一个数.
         //capitals[rand.nextInt(capitals.length)]这里表示
         //随机产生的这个数就是字符数组capitals的下标
         //这样就能确定拼接的具体是字符数组capitals中的
         //那个字符了
         //这里整体表示的是随机读取一个大写字母.
         cb.append(capitals[rand.nextInt(capitals.length)]);
         //这里同上,表示的是随机读取四个小写字母和四个元音字母
         for(int i=0;i<4;i++){
            cb.append(vowels[rand.nextInt(vowels.length)]);
            cb.append(lowers[rand.nextInt(lowers.length)]);
         }
         //最后拼接一个空字符串
         cb.append(" ");
         //返回值10.
         return 10;   
      }
      //程序执行入口main方法
      public static void main(String[] args){
         //创建类Scanner的对象,将类RandomWords的对象实例
         //最为实际参数传入,它实现了接口Readable,所以没问题。
         //new RandomWords(10)初始化值为10,表示count的值为10,
         //表示需要读取10个结果
         Scanner s = new Scanner(new RandomWords(10));
         //while循环
         while(s.hasNext()){
            //打印拼接的每个字符数组
            System.out.println(s.next());
         }
      }
   }

结果示例:
JavaSE基础知识(十九)--Java接口之适配接口_第4张图片
Readable接口只要求实现read()方法,在方法read()内部,将输入内容添加到CharBuffer参数中,或者再没有任何输入时返回-1。
假设你有一个还未实现Readable的类,怎样才能让Scanner作用于它呢?
代码示例:

// 产生一个随机浮点数的类
   //类RandomDoubles
   public class RandomDoubles{
      //创建随机类Random的对象实例
      private static Random rand = new Random(43);
      //方法next()
      public double next(){
         //返回随机对象读取的一个Double类型的值
         return rand.nextDouble();
      }
      //程序执行入口main方法
      public static void main(String[] args){
         //创建类RandomDoubles的对象实例
         RandomDoubles rd = new RandomDoubles();
         //for循环,循环7次
         for(int i=0;i<7;i++){
            //每次循环输出一个Double值(通过调用它的方法next())
            System.out.println(rd.next() + " ");
         }
      }
   }
   //再次使用适配器模式,但是在这个例子中,适配的类可以通过继承和实现Readable
   //接口来实现,因此,通过使用interface关键字提供的伪多重继承的机制,
   //我们可以生成即是RandomDoubles又是Readable的新类。
   //类AdaptedRandomDoubles继承类RandomDoubles实现接口Readable
   //所以它既是一个RandomDoubles又是一个Readable
   public class AdaptedRandomDoubles extends RandomDoubles 
   implements Readable{
      //int类型的类变量count
      private int count;
      //构造方法,带一个int类型的形式参数count
      public AdaptedRandomDoubles(int count){
         //初始化类变量int
         this.count = count;
      }
      //实现接口Readable接口的方法read,带一个CharBuffer类型的形式参数
      //cb
      public int read(CharBuffer cb){
         //如果count--表达式的值为0
         //则结束此方法的调用,返回值-1
         if(count-- == 0){
            //返回值-1
            return -1;
         }
         //调用类Double的方法toString(),放入实际参数--Next()
         //方法的返回结果,这个Next()方法是父类RandomDoubles
         //的方法,将结果赋值给String类型的变量result
         String result = Doubles.toString(next()) + " ";
         //将result的值拼接至cb中
         cb.append(result);
         //返回result的长度。
         return result.length();
      }
      //程序执行入口main方法
      public static void main(String[] args){
         //创建Scanner类对象实例,将类AdaptedRandomDoubles
         //的对象实例作为实际参数传入。
         Scanner s = new Scanner(new AdaptedRandomDoubles(7));
         //while循环
         //如果s中还有下一个Double值(hasNextDouble())
         while(s.hasNextDouble()){
            //打印出这个Double值。
            System.out.println(s.nextDouble() + " ");
         }
      }
   }

在上面示例代码这种方式中,我们可以在任何现有类之上添加新的接口(比如让任何一个类去实现接口Readable,那么这个类就能适用于类Scanner),所以这意味着让方法接受接口类型,是一种让任何类都可以对该方法进行适配的方式,这就是使用接口而不是类的强大之处。
PS:时间有限,有关Java SE的内容会持续更新!今天就先写这么多,如果有疑问或者有兴趣,可以加QQ:2649160693,并注明CSDN,我会就博文中有疑义的问题做出解答。同时希望博文中不正确的地方各位加以指正。

你可能感兴趣的:(Java,SE)