接口的作用

来源:互联网 发布:手机吉他调音软件 编辑:程序博客网 时间:2024/06/14 15:12

接口定义一套规范,描述一个“物”的功能,要求如果现实中的“物”想要成为可用,就必须实现这些基本功能。接口这样描述自己:

“对于实现我的所有类,看起来都应该像我现在这个样子”。

采用一个特定接口的所有代码都知道对于那个接口会调用什么方法。这便是接口的全部含义。接口常用来作为类与类之间的一个“协议”。接口是抽象类的变体,接口中所有方法都是抽象的,没有一个有程序体。接口除了可以包含方法外,还能包含常量。

比如用接口描述发动机,要求机动车必须要有“run”功能,至于是谁(摩托还是宝马),怎么实现(跑或者飞),应该是什么样(前驱还是后驱),不是接口关心的。应为接口为抽象而生。作为质检总局,要判断这辆车是否合格,只要按照“接口”的蒂尼一条条验证,这辆车不能“run”,那它就是废品,不能通过验收。但是,如果汽车实现了接口中本来不存在的方法“music”,并不认为有什么问题。接口就是一种契约。因此,在程序里,接口的方法必须被全部实现,否则将报“fatel”错误,代码如下所示

<?phpinterface Mobile{    public function run();}class Plain implements Mobile{    public function run()    {        echo '我是飞机';    }    public function fly()    {        echo '飞机';    }}class Car implements Mobile{    public function run()    {        echo '我是车';    }}class Machine{    public function demo(mobile $obj)    {        $obj->fly(); //mobile接口是没有这个方法的    }}$mechine = new Machine();$mechine->demo(new Plain());$mechine->demo(new Car());
在这段代码里,定义一个机动车接口,其中含有一个发动机功能。然后用飞机类实现这个接口,并增加了飞行方法。最后,在一个机械检测类中对机动车进行检测(用类型约束指定要测试的是机动车这个接口)。但是,此检测线测试的确实机动车接口中不存在fly方法,直到遇到car的对象因不存在fly方法而报错。

这段代码实际上是错误的,不符合接口语义。但是在PHP里,对plain的实例进行检测时是可以运行。也就是说,在PHP里,只关心是否实现这个方法,而不关心接口语义是否正确。

按理说,接口应该是起一个强制规范和契约的作用,但是这里对接口的约束并没有起效,也打破了契约,对检测站这个类的行为失去控制。可以看看在Java里是怎么处理的,如下图所示


java认为,接口就是一种type,即类型。如果你打破了我们之间的契约,你的行为变得无法控制,那就是非法的。这符合逻辑,也符合现实世界。这就真正起到了接口作为规范的作用。

接口不仅规范接口的实现者,还规范接口的执行者,不允许调用接口中不存在的方法。当然这并不是说一个类如果实现了接口,就只能实现接口中才有的方法,而是说,如果针对的是接口,而不是具体的类,则只能按照接口的约定办事。这样的语法规则对接口的使用是有利的。让程序更健壮。根据这个角度讲,为了保证接口的语义,通常一个接口的实现类仅实现该接口所具有的方法,做到专一,当然这也不是一成不变的。

由上面的例子可以看出,PHP里接口作为规范和契约的作用打了折扣。上面例子实际就是一个典型的面向接口编程的例子。更具这个例子,可以很自然地想到使用接口的场合,比如数据库操作,缓存实现等。不用关心我们所面对的数据库是MySQL还是Oracle,只需要关心面向Database接口进行具体业务的逻辑相关的代码,这就是面向接口编程的来历。在这里,Database就如同employee一样,针对这个接口实现就好了。缓存功能也一样,我们不关注缓存是内存缓存还是文件缓存,或者是数据库缓存,只关注他是否实现了Cache接口,并且它只要实现了Cache接口,就实现了写入缓存和读取某条缓存中的数据及清除缓存这几个关键的功能点。

通常在大型项目里,会把代码进行分层和分工。核心开发人员和技术经理编写核心的流程和代码,往往是以接口的形式给出,而基础开发人员则针对这些接口,填充代码,如数据库操作等。这样,核心技术人员把更多精力投入到技术攻关和业务逻辑中,前端针对接口编程,直管在Action层调用Service,不管实现细节;而后端则要负责Dao和Service层接口实现。这样,就实现了代码分工与合作。

1 0
原创粉丝点击