Interface
1. Abstract class: 如果一个类中有abstract function那么这个类一定要被定义为抽象类,不然编译器报错
2. 抽象类不能被用于直接创建对象,因为编译器知道它不完整
3. 派生类继承抽象类一定要先实现它所有的抽象方法不然它也还是抽象类要加上abstract
4. Interface 类比抽象类更进一步,所有的方法都是抽象的,都是没有实现的
5. Interface接口可以实现一个派生类“继承”多个接口,而在java中一个派生类只能继承一个类
6. Interface中的属性,field,自动隐式定义为static and final ,接口实现的时候不用extends而用implements
7. 接口里面的方法不需要加abstract,本身就是abstract了,而且接口中的方法本身就是public了
8. 一个派生类实现了接口中的所有方法,那么这个派生类就是正常的class了,否则它就是抽象类
9. covariant return type:基类中某个函数在派生类中可以override,并且返回值得是基类中那个函数返回值的子类,或者就是相同类型
class Grain {
public String toString() { return "Grain"; }
}
class Wheat extends Grain {
public String toString() { return "Wheat"; }
}
class Mill {
Grain process() { return new Grain(); }
}
class WheatMill extends Mill {
Wheat process() { return new Wheat(); }
}
public class CovariantReturn {
public static void main(String[] args) {
Mill m = new Mill();
Grain g = m.process();
System.out.println(g);
m = new WheatMill();
g = m.process();
System.out.println(g);
}
} /* Output:
Grain
Wheat
*///:~
- 接口适配器Adapter,使用这个来适应别人写的无法改变的接口
01 //类库代码(即别人写的,不可修改)
02 class WaveForm{
03 private static long counter;
04 private final long id = counter++;
05 public String toString(){
06 return "WaveForm id: " + id;
07 }
08 }
09
10 //类库代码,处理WaveForm
11 class Fliter{
12 public String name(){
13 return getClass().getSimpleName();
14 }
15
16 //和我们的接口微妙不同
17 public WaveForm process(WaveForm input){
18 return input;
19 }
20 }
21
22 //很遗憾BOSS告诉你我们的代码必须遵照这个接口
23 interface Processor {
24 String name();
25 Object process(Object obj);
26 }
27
28 //Fliter是别人写的,我们无法修改,所以使用适配器
29 //适配器,将Fliter接口适配
30 class FliterAdapter implements Processor{
31 //持有一个fliter
32 private Fliter fliter;
33
34 public FliterAdapter(Fliter fliter) {
35 this.fliter = fliter;
36 }
37
38 @Override
39 public String name() {
40 return fliter.name();
41 }
42
43 @Override
44 public Object process(Object obj) {
45 //现在接口终于匹配了
46 return fliter.process((WaveForm)obj);
47 }
48 }
49
50 public class Apply{
51 public static void process(Processor p, Object obj){
52 System.out.println("Process: " + p.name());
53 System.out.println(p.process(obj));
54 }
55
56 public static void main(String[] args) {
57 process(new FliterAdapter(new Fliter()), new WaveForm());
58 }
59 }
- 接口的作用
1) 为了能让一个子类向上转变到不止一种形态
2) 防止程序员直接用这个接口创建一个对象,因为我们不想他们这么做
3) 还可以同一个接口很多很多实现 - 在选择是接口还是抽象类的时候,最好先选择抽象类
- 一个接口可以通过extends另一个接口实现,添加新的抽象方法
interface Monster {
void menace();
}
interface DangerousMonster extends Monster {
void destroy();
}
interface Lethal {
void kill();
}
class DragonZilla implements DangerousMonster {
public void menace() {}
public void destroy() {}
}
interface Vampire extends DangerousMonster, Lethal {
void drinkBlood();
}
class VeryBadVampire implements Vampire {
public void menace() {}
public void destroy() {}
public void kill() {}
public void drinkBlood() {}
}
- 不能一个接口继承另外两个有相同函数名以及参数名,但是返回值不同的接口
- 一个方法是拿接口当参数的,那么你只要用一个类来实现这个接口,那么你就可以把这个类当参数传进去了
- 接口可以嵌套定义在一个类(可以为private或者public)中,或者一个接口(一定是public)中
- 如果一个接口在类中被定义为private说明,实现这个接口的类不能upcasting到这个接口,而且其他类也不能实现这个接口
- Java factory模式,其中factory是抽象类或者是接口