引子:小时候布置作业的时候,我的老师一般会把布置的作业写在一张纸上,把纸交给课代表,再有课代表把作业告诉同学们,收作业的时候也是,老师一般会问课代表要作业,收作业的工作并不会亲自动手,干活的始终都是课代表。
所以,打我们上小学开始,我们就已经开始接触面向接口了,课代表就是老师与学生之间的接口。再抽象一点,比如小学班里只有一个老师,教语文,数学,英语三门课,有个小班长,是老师的助理,班长手下有三个课代表,分别对应于三门课,收作业的时候,老师只需要对班长说“收作业”(班长是接口,或者抽象类),班长会对三个课代表说“收作业”(多态,三个课代表是实现),这样就达到了目的,而不需要对每个课代表都说一遍“收XX作业”。当指令需要带动时,老师只需要对班长说“把每门的作业上面写上title”,班长继续相关指令“每门作业写上是哪门课的”,这样班里同学就会在语文作业本上写上“语文”两个大字,数学本上写上“数学”,以此类推。
看到这里大家应该对面向接口有一个初步的了解了,当一个工程的实现类比较多的时候,比如说课代表比较多,老师是不需要对每个课代表发布指令的,因为每个课代表的基本职能是类似的,只是实现不一样罢了,所以就可以抽象出一个接口(班长),让课代表各自实现班长的方法,这样以后老师下达指令(编程)就只需要面向班长就可以了。而不需要对每个课代表所谓面向接口编程。
下面看看官方版解释:
接口应该是定义与实现的分离。接口的本身反应了系统设计人员对系统的抽象理解。一般的,当我们在编写一个系统或者工具的时候,我们在意的是,这个工具能做什么,而不是它是怎么做的。即,我们不关注它是怎么实现的,按照这种思想来编程,即面向接口编程。
画外音:正如很多书中,接口名的定义一般都是readable,moveable等等,从名称上就可以看出接口是表示其实现类能(can do )做什么。普通类(包括抽象类)则表示其子类是(is a kind of)什么,Thinking in Java中的命名很有门道。
再来看面向接口与面向对象编程的关系
首先我们要确定的是,面向接口属于面向对象的范畴,个人觉得,面向接口只是对面向对象又做了一层封装,将what to do 和how to do 做了分离,比如最简单的计算机主板给我们提供了各种各样的接口,拿USB接口来说,对计算机而言,需要一个输入设备,至于你插的是普通键盘还是机械键盘,它都不关心,计算机只面向了USE插口,只要是符合这个插口规范的设备,都一视同仁,并不需要对滚轮鼠标、光电鼠标、甚至各种牌子的鼠标分别处理。
再者,来看JAVA的跨平台性,JVM本身也是面向接口的,对上提供的JDK库是统一的,对各个操作系统的编译器是不同的,只要你编写的代码符合对上的接口,对于任何OS都一视同仁,并不需要码农对每种OS分别处理(这所谓一次编写,到处运行)这下大家看到面向对象的好处了吧。接口层,将规范(what to do)与实现(how to do)做了分离,再配合多态(接口的意义,希望大家还记得各科课代表的例子),可以轻易的提升软件灵活性以及可维护性。
下面我们举一个学习多态时候的小例子,来看一下什么叫面向接口:
既然是接口,首先定义一个接口:
package Gof; public interface Runable { void walk(); void run(); void stop(); }
好了,接下来我们针对Runable编写几个实现类
package Gof; public class InterfaceOriented { //参数设为接口,从而避免了为每个实现类定义一个相同的方法 //这个方法还可以修改逻辑的顺序,比如stop->walk->run->walk->stop等等,只需一份就好 private static void doEverything(Runable runable){ System.out.println("now I am ready to run...."); runable.run(); System.out.println("I am tired and wanna walk for a while..."); runable.walk(); System.out.println("I am totally tired wanna stop...."); runable.stop(); } public static void main(String[] args) { Runable person = new Person(); Runable cat = new Cat(); Runable dog = new Dog(); Runable fox = new Fox(); doEverything(person); } } class Person implements Runable{ @Override public void run(){ System.out.println("people run...."); } @Override public void walk(){ System.out.println("people walk...."); } @Override public void stop(){ System.out.println("people stop...."); } } class Cat implements Runable{ @Override public void run(){ System.out.println("cat run...."); } @Override public void walk(){ System.out.println("cat walk...."); } @Override public void stop(){ System.out.println("cat stop...."); } } class Dog implements Runable{ @Override public void run(){ System.out.println("dog run...."); } @Override public void walk(){ System.out.println("dog walk...."); } @Override public void stop(){ System.out.println("dog stop...."); } } class Fox implements Runable{ @Override public void run(){ System.out.println("fox run...."); } @Override public void walk(){ System.out.println("fox walk...."); } @Override public void stop(){ System.out.println("fox stop...."); } }
如果突然来了一只狼wolf,那么只需要将wolf作为参数传进去即可,这里我们定义的doEverything方法是面向Runable接口的,只要符合这个标准(实现类)都可以直接插入作为参数。是不是很像只要符合鼠标规范的,就可以直接插入USB接口?
当然面向接口编程中指的接口并非狭义的接口,而是更高层的抽象,就拿本例来说,还可以做更高一层的抽象,比如下篇博文要介绍的工厂模式。
相关推荐
白话智能体编程.pdf
======白话面向智能体编程==========
白话windows编程.rar
《白话 Windows 编程》EXE格式电子书,收藏版!!!
白话windows编程,这本书深入浅出,很适合初学者
首先,什么是对象呢,这个答案太不好回答了,因为什么都是对象.对出租车司机来说,车就是对象
软件设计本质论—白话面向对象 不同的人在谈面向对象编程(OOP)时所指的含义并不相同。有人认为任何采用图形界面的应用程序都是面向对象的。有人把它作为术语来描述一种特别的进程间通信机制。
白话C++编程.rar
很好的C++学习资料,对学习很有帮助!快来下载
白话函数式编程!.zip,Jargon from the functional programming world in simple terms!
白话c++.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-...
白话机器学习的数学-立石贤吾-源代码.zip
白话机器学习的数学.docx
白话中台战略-中台到底长啥样 (2).pdf白话中台战略-中台到底长啥样 (2).pdf白话中台战略-中台到底长啥样 (2).pdf白话中台战略-中台到底长啥样 (2).pdf白话中台战略-中台到底长啥样 (2).pdf白话中台战略-中台到底长啥...
《罗织经》白话全译.doc
2008版 白话c++》教程完全从0开始 面向所有非软件专业的人员 纸质书将于近期出版…
以白话的方式解读了c++,中国编程大师的力作,语言简洁幽默,讲解清晰,顶起来!