接口
接口和内部类提供了很好的接口与实现分离的方法。
完全解耦
在多态中,一个方法操作的是类,那么你可以使用这个类及其子类,代码会有很好的复用性。但是对于不在这个继承结构中的某个类,就没有办法了。
而接口却可以放宽这种限制。
多重继承
多重继承实际上就是组合多个类的接口。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 | //: interfaces/RandomDoubles.java |
为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
*///:~