接口回调 入门

有三个类,他们之间的关系如下:
 
interface A
class B implements A
class C implements A
 
要获得B类的对象,一般的写法是:B b = new B();
还有一种写法,叫接口回调,写法是:A b = new B();
意思是,用接口的变量b,去引用B的对象。接着就可以用b去调用B中的方法。但调用的方法必须是接口里定义了的。
 
接口回调带来的最大好处就是灵活性,例如必要时可以直接用b去引用C的对象:b = new C();
 
例子
interface People {
    void peopleList();
}
 
class Student implements People {
    public void peopleList(){
        System.out.println("I’m a student.");
    }
}
 
class Teacher implements People {
    public void peopleList() {
        System.out.println("I’m a teacher.");
    }
}
 
public class Example {
    public static void main(String args[]) {
        People a; // 声明接口变量
        a = new Student(); // 实例化,接口变量中存放对象的引用
        a.peopleList(); // 接口回调
        a = new Teacher(); // 实例化,接口变量中存放对象的引用
        a.peopleList(); // 接口回调
    }
}
输出:
 
I’m a student.
I’m a teacher.
 
概念就是这样。下面说开发中的常见的例子。
 
最最常见的接口回调的例子就是
 
List list = new ArrayList(); 
 
这里的List就是接口,ArrayList是普通类。(如下图,白色是接口,红色的普通类。)
 
 
List list = new ArrayList(); 这种写法正是接口回调的写法。这时,list只能调用接口List中定义了的方法。
 
假如,你在写一个很大的第三方库,并决定用LinkedList来实现这个库的核心。如果你的这个库非常依赖于访问list里的元素,最后你会发现使用LinkedList(访问时间O(n))是个非常糟的设计。这时候你才意识到,应该用ArrayList(访问时间O(1))  。
 
如果你之前是使用接口回调的写法,那么做这个改变十分容易。只要这样修改一下: 
List list = new LinkedList();
改为
List list = new ArrayList(); 
 
而如果你用普通的写法,LinkedList list = new LinkedList()来实现你的核心库,那么修改就不那么容易了。因为不能保证其余代码没有使用LinkedList类专属的方法。 
 
总而言之,这个选择仅仅是一个设计的问题......但这种设计是(尤其是工作在大型项目时)非常重要,因为它可以让你不用破坏现有的代码,就能实现特殊的改变。 
 
posted @ 2015-04-24 00:00  斥斥  阅读(205)  评论(0编辑  收藏  举报