01BIM社区

 找回密码
 立即注册

扫一扫,访问微社区

查看: 3599|回复: 0

JAVA 接口是干吗用的

[复制链接]

14

主题

21

帖子

109

积分

注册会员

Rank: 2

积分
109
发表于 2016-9-29 10:20:16 | 显示全部楼层 |阅读模式
            接口是干嘛用的





接口只规定了对象必须实现的方法,但是没有任何实现,也就是说没有执行逻辑的有效代码。

要想完成具体业务还是需要编写实现类来实现接口。

那么问题来了,既然具体业务实现仍然是由接口的实现类来完成的,那么要编写接口有什么卵用?



先来看看什么样的语言有接口语法
注意这里说的是编写程序的时候使用的接口语法
至于其他形式完成接口功能的方式不讨论
Java有,C++有,C#有
JavaScript没有,Python没有,Ruby没有



可以看到需要声明接口的语言都是在传入接口参数时进行语法检查的
也就是说如果声明了这样一个方法:

void quest(Httq q);

那么调用这个方法时只能传入一个参数
而且这个参数的类型必须是Httq
当然根据类型转换的原则
类的子类,接口的实现类也可以

至于为什么这些语言必须做强制类型检查
那就是另外的问题了

好,基于这个事实我们再继续思考
quest方法只接受Httq类型的参数
那么我就在Httq类的实现里编写业务逻辑代码就是了啊

这样当然是可以的,如果Httq类的代码我们可以修改的话
我们可以假设Httq类里实际上只暴露了一个方法给外界:

public String getMsg();

而quest方法中有一行代码是这样写的:
String msg=q.getMsg();

这样Httq里承载了某些数据,而getMsg方法就是把它承载的数据
整理成字符串形式返回

看起来很简单不是吗?

有一天我们突然发现,Httq承载数据有不同的格式
最简单的是纯文本
有的是字节数组
有的是xml树形结构
有的甚至是一个数据库查询结果的链接

于是我们的getMsg方法中就出现了好多的条件和判断
这一段用来处理字节数组,另一段用来处理xml

到目前为止,一切都可以工作的
然后我们将它打包发布出去了

一个星期之后,另一个团队基于我们的程序包开发新的功能
他们发现,Httq类需要承载一个Ajax请求作为数据
但是他们已经无法再修改Httq类了

当然他们也是很聪明的
他们编写了一个HttAjax类继承了Httq类
覆盖了getMsg()方法
与此同时HttAjax暴露了一个方法用来获取Ajax数据的版本号
public String getVersion();
一切又可以有条不紊地进行了

镜头拉回我们的团队
一个月之后
我们发现了我们已经发布的程序包有重大的安全隐患
并且第一时间通知了刚才那个Ajax团队
Ajax团队让我们修复一下然后把新的程序包发布出来
当然,这正是我们的工作
所以我们光速修复了安全隐患
重新制定了字节数组、XML甚至数据库链接的规范
新的规范要健壮多了
然后,当然我们也是很人性化的
为了兼容旧的数据,我们在Httq类里声明了一个方法
public String getVersion();
这个方法返回所承载数据的版本号
用来区别对待新规范和旧规范

我们满怀诚意的将新版本发布了出去
第一天一切似乎都很顺利
第二天Ajax团队报告说过去24小时的数据全部丢失了
我们检查了我们所有的代码,没有发现问题
无奈之下,实习生工程师被派到Ajax团队调查问题

结果是令人沮丧的
因为HttAjax类覆盖了getVersion()方法
导致quest方法调用getVersion()时得到了错误的值
首先我们向Ajax团队建议
你们把getVersion()改成另一个名字吧
他们拒绝了,因为他们的代码里到处都有getVersion()的调用
于是他们把同样的建议返回给了我们
我们也拒绝了,因为我们的代码里面同样到处都有getVersion()的调用

这下好了,我们双方都必须花费很多精力重构代码了
当然,这已经不管我的事,因为我的辞职报告已经交上去了


我们跳回“看起来很简单不是吗?”这一行
当我们发现我们要承载不同的数据时
我们将Httq改成了一个接口

接口中只声明了一个方法
public String getMsg();

我们根据每一种需要承载的数据都编写一个类实现这个接口
HttqText
HttqXML
HttqDB
和一个又一个的判断说再见吧

因为对象自己肯定知道自己要处理的是xml还是数据库链接
妈妈再也不用担心数据类型判断的问题了

Ajax团队也仅仅只是声明了一个新的类实现了Httq接口

关于后面出现的安全隐患的问题
接口是不可以改变的,那我们的getVersion方法怎么办?

当然,因为HttqText类我们还是可以修改的,不是吗?
所以我们在HttqText类添加了getVersion()方法

但是,太奇怪了,quest方法里面却不能调用这个方法
void quest(Httq q);

原因很简单,强制类型检查的结果
Httq是个接口,接口也是类型的一种

变量q的类型是Httq就可以作为参数传进来
在方法quest中,变量q指代的仅仅是一个Httq对象
虽然我们知道Httq接口不可能凭空产生对象
但是Httq接口里声明了对象q可以调用哪些方法
因为对象q肯定是一个实现了Httq接口的类的对象

但是相对的,在quest方法中我们也只知道对象q实现了Httq接口
它有没有实现其他方法,它是哪个类的对象
这些只有在运行到此的时候才知道

所以我们不能这样调用
//q.getVersion()   //这是错误的做法

因为q不见得是HttqText对象

那要怎么办,要判断一下对象q的类型吗?

根本就不用担心因为quest方法也是在一个接口里声明的
新版本的数据和旧版本的数据根本不是在一个实现类里面处理的!

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|01BIM社区 - 最专业的BIM技术交流平台 ( 渝ICP备15000873号 )

GMT+8, 2024-5-4 15:52 , Processed in 0.052741 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表