java编程思想(九): 接口

接口

接口和内部类提供了很好的接口与实现分离的方法。

完全解耦

在多态中,一个方法操作的是类,那么你可以使用这个类及其子类,代码会有很好的复用性。但是对于不在这个继承结构中的某个类,就没有办法了。

而接口却可以放宽这种限制。

多重继承

多重继承实际上就是组合多个类的接口。

1
2
// B为抽象类或基类,C1,...为接口
class A extends B implements C1, C2, C3 ...

则如上A可以向上转型为B, C1, C2 …, 因此可以很方便的复用代码

适配接口

接口最大的用处就是一个接口可以有很多不同的实现。于是如果一个方法以一个接口类型为参数,则使用者可以通过改变接口的实现方式和传入的对象,来产生不同的行为。

比如Java中的Scanner类,它的构造器接收的是一个Readable接口。如果创建了一个新的类,想让Scanner作用于它,只需实现Readable接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//: interfaces/RandomWords.java
// Implementing an interface to conform to a method.
import java.nio.*;
import java.util.*;

public class RandomWords implements Readable {
private static Random rand = new Random(47);
private static final char[] capitals =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final char[] lowers =
"abcdefghijklmnopqrstuvwxyz".toCharArray();
private static final char[] vowels =
"aeiou".toCharArray();
private int count;
public RandomWords(int count) { this.count = count; }
public int read(CharBuffer cb) {
if(count-- == 0)
return -1; // Indicates end of input
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(" ");
return 10; // Number of characters appended
}
public static void main(String[] args) {
Scanner s = new Scanner(new RandomWords(10));
while(s.hasNext())
System.out.println(s.next());
}
} /* Output:
Yazeruyac
Fowenucor
Goeazimom
Raeuuacio
Nuoadesiw
Hageaikux
Ruqicibui
Numasetih
Kuuuuozog
Waqizeyoy
*///:~

如果某个类没有实现Readable接口,那应该怎么办呢?只需extends,并实现Readable接口即可。其实就是一个适配器,适配Readable接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//: interfaces/RandomDoubles.java
import java.util.*;

public class RandomDoubles {
private static Random rand = new Random(47);
public double next() { return rand.nextDouble(); }
public static void main(String[] args) {
RandomDoubles rd = new RandomDoubles();
for(int i = 0; i < 7; i ++)
System.out.print(rd.next() + " ");
}
} /* Output:
0.7271157860730044 0.5309454508634242 0.16020656493302599 0.18847866977771732 0.5166020801268457 0.2678662084200585 0.2613610344283964
*///:~

为RandomDouble 适配Readable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//: interfaces/AdaptedRandomDoubles.java
// Creating an adapter with inheritance.
import java.nio.*;
import java.util.*;

public class AdaptedRandomDoubles extends RandomDoubles
implements Readable {
private int count;
public AdaptedRandomDoubles(int count) {
this.count = count;
}
public int read(CharBuffer cb) {
if(count-- == 0)
return -1;
String result = Double.toString(next()) + " ";
cb.append(result);
return result.length();
}
public static void main(String[] args) {
Scanner s = new Scanner(new AdaptedRandomDoubles(7));
while(s.hasNextDouble())
System.out.print(s.nextDouble() + " ");
}
} /* Output:
0.7271157860730044 0.5309454508634242 0.16020656493302599 0.18847866977771732 0.5166020801268457 0.2678662084200585 0.2613610344283964
*///:~