适应界面

时间:2011-08-04 14:22:08

标签: java interface

在“适应界面”一节中,“Thinking in Java”第238页,作者介绍了以下示例

public class RandomDoubles {
    private static Random rand = new Random(47);
    public double next() { return  rand.nextDouble();}
    public static void main(string[] args){
    RandomDouble rd = new RandomDoubles();
    for (int i=0; i<7; i++)
        System.out.print(rd.next()+" ");
    }
}

与此示例相关联,作者声明

  

假设您有一个尚未实现Readable(接口)的类 - 您如何使它与Scanner(类)一起使用?

     

因为您可以通过这种方式将接口添加到任何现有类,这意味着采用接口的方法为任何类提供了一种适用于该方法的方法。这是使用接口而不是类的强大功能。

但是,我不太明白这个陈述是如何反映在这个例子中的。例如,界面在哪里添加? “采用接口的方法”中的方法是指什么?

3 个答案:

答案 0 :(得分:3)

我甚至会说给定的文字与您提供的代码片段相关联。

文字

该文本描述了接口的使用(据我所知,RandomDoubles不是),特别是Readable。我并不熟悉Scanner的工作方式,因为我最近已经离开了Java一段时间。

但是,Scanner可能会将Readable对象作为参数,然后从中读取。这意味着在Scanner / read中的某处,出现如下代码。

Readable object = (parameter that is an object that implements Readable);

...
//in Scanner.read
object.read(buffer);

Readable对象可以是实现Readable的任何类之一,可以是您自己的自定义类,也可以是FileReader,BufferedReader,InputStreamReader ......

因为这些类实现了Readable,因此必须定义read(缓冲区),所以它们可以在Scanner类中互换使用,方法是将它们称为该Interface类型的对象。

该文本特别提到您可以将该功能添加到任何现有类,方法是使其实现Readable,然后定义其read(buffer)方法如何将字符输出到缓冲区。

代码片段

附加的代码片段只是指定一个自定义类可以使用一个Random对象的方式,但只暴露它为使用该类生成任意程序的随机双精度的能力。这与接口无关。

答案 1 :(得分:0)

//Jim Colmenero - Application Architect - colmeneroj@videotron.ca

//It's been a while, but quite easy really.


import java.nio.CharBuffer;
import java.util.Random;
import java.util.Scanner;

public class RandomDoubles implements Readable{

    private static final long seed = 47;

    private static Random randomNbrGenerator = new Random(seed); 

    private int count;  // you just want 5 doubles printed 

    public RandomDoubles(int count) {  // ctor
        this.count = count;
    }

    public int read(CharBuffer cb) {
        if (count-- == 0)
            return -1; // Indicates end of input

        cb.append(Double.toString(randomNbrGenerator.nextDouble()));   
        cb.append(" ");
        return 0; // Number of characters appended- any positive value for this example
    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner( new RandomDoubles(5) );

        while (scanner.hasNext()) { 
           System.out.println(scanner.next());  
        }
    }
}

// Output:

0.7271157860730044
0.5309454508634242
0.16020656493302599
0.18847866977771732
0.5166020801268457

Process finished with exit code 0

===================================================================================

Now, another way to answer the question, is NOT TO TOUCH the original code of the 
RandomDoubles  class, but instead add and execute an Adapter class like so:


import java.nio.CharBuffer;
import java.util.Scanner;

public class AdapterRandomDoubles
    extends RandomDoubles
    implements Readable {

    private int numberOfDoubleValues;

    public AdapterRandomDoubles(int numberOfDoubleValues) {      // ctor
        this.numberOfDoubleValues = numberOfDoubleValues;
    }
    public int read(CharBuffer cb) {
        if (numberOfDoubleValues-- == 0)
            return -1; // Indicates end of input

        cb.append(Double.toString(nextRandomNbr()));  
        cb.append(" ");
        return 0;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(new AdapterRandomDoubles(5)); // 5 random numbers
        while (scanner.hasNext())
            System.out.println(scanner.next());
    }
}

 ==== I guess that's it for now. So remember, debug to get the hang of it and have fun
 ==== like I do. 

答案 2 :(得分:0)

在解决方案中,
替换行:cb.append(Double.toString(nextRandomNbr()));
行:cb.append(Double.toString(next()));