Java标识接口的使用方法

标识接口是没有任何方法和属性的接口。标识接口不对实现它的类有任何语义上的要求,它仅仅表明实现它的类属于一个特定的类型。

标接口在Java语言中有一些很著名的应用,比如java.io.Serializable和java.rmi.Remote等接口便是标识接口。标识接口,当一个类实现了一个标识接口之后就像是给自己打了个标签。

为此,我们通过一个通俗而有趣的示例!这个示例是设计一个猎人,其持有一把智能猎枪,这就是说这把猎枪会自动识别人类,若发现瞄准的目标是人类,就不会开火,而其它的任何事物都通杀。

为此,我们使用了下面三个接口:

一个用来表示万事万物的SomeThing

public interface SomeThing {}

人类的接口:

public interface Humans extends SomeThing{}

动物的接口:

public interface Animals extends SomeThing{}

然后是一系列的实现:

中国人:

public class Chinese implements Humans {}

日本人:

public class Japanese {}

狗:

public class Dog implements Animals {}

妖怪(他很聪明,给自己帖上了人的标签):

 public class Monster implements Humans {}

下面这个程序的核心部分,猎人类及客户端程序:

public class Hunter{

public void fire(Object target)
{
   if(target instanceof Humans){
    System.out.println("这下完了,打中了一个人,该去坐牢了!");
   }else{
     System.out.println("恭喜你,打中了一只动物!");
   }
}
//智能的枪
public void intelligentFire(Object target)
{
   if(target instanceof Humans){
    return;
   }
   System.out.println("开了一枪!"+target.getClass());
   //下面进行秒杀等相关处理
   //销毁他
   target=null;
}

public static void main(String[] args) {
  Hunter hunter=new Hunter();
  Object[]
  objects =new Object[]{new Dog(),new Japanese(),new Japanese(),new Chinese(),new Monster(),new SomeThing(){}};
    for(int i=0; i<objects.length; i++){
       hunter.intelligentFire(objects[i]);
    }
}

运行程序,你会发现输出类似下面结果:

开了一枪!class springroad.demo.taginterface.Dog
开了一枪!class springroad.demo.taginterface.Japanese
开了一枪!class springroad.demo.taginterface.Japanese
开了一枪!class springroad.demo.taginterface.Hunter$1

由此可见,智能猎枪瞄准6个目标,开了4枪。只对Chinese、及Monster的实例没有开枪。因为这里讨论的是标签接口,虽然Humans没有任何方法,但从智能猎枪的角度来看,他就是通过这个标签来判断是否可以开火的。他不用管也管不了目标的层次等级关系(比如Japanese肯定很非常鲜明等级结构),即继承关系。他也管不了目标的来自于哪儿。比如,是用new操作符创建,还是从容器中取,或者是从网络某个地方加载一个。

Hunter只是制订了一个简单的规则,你要想不让我的枪对你开火,你就必须在自己身上帖上一个Humans的标签。也就是说你必须遵守这个规则。

现在回过头来看,因为妖怪Monster真身应该是一条蛇或其它什么动物,但是他懂得Hunter制订的规则,于在巧妙的给自己帖上了一个Humans的标签,以致于欺骗了我们的智能猎枪。

而Japanese则自认为自己了不起,不按规则办事,我就不理你Hunter制订的规则,什么Humans标签,我就是不用。于是放到我们的程序中当然就只有挨杀的份了。

由此可见,空接口(标签接口)的重要性,在像本例中,给不给自己帖上标签,这是一个性命莜关的问题。其实在OO的世界中,空接口可以算是最高的层像。

(0)

相关推荐

  • Java的异常类型总结

    Java的设计目的是让程序员有机会设计一个没有错误的应用程序.当应用程序与资源或用户交互时,程序员可能会知道一些异常,这些异常是可以处理的.不幸的是,也有程序员无法控制或简单忽略的例外情况.简而言之,并不是所有的异常都是相同的,因此程序员需要考虑几种类型. 异常是导致程序无法在其预期的执行中运行的事件.异常有三种类型--检查异常.错误和运行时异常. The Checked Exception(检查异常) 已检查异常是Java应用程序应该能够处理的异常.例如,如果应用程序从文件中读取数据,它应该能

  • Java List中数据的去重

    list中数据的去重,通常使用将list转换为set,简单直接,因为set集合的特点就是没有重复的元素.需要考虑一下两种情况: 1.List集合中的数据类型是基本数据类型 可以直接将list集合转换成set,就会自动去除重复的元素. 如下示例: public class Test { public static void main(String[] args) { List list = new ArrayList(); list.add(11); list.add(12); list.add(

  • Java编程接口回调一般用法代码解析

    接口回调是指:可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法.实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调. Java接口回调一般用法:实现接口实际上和继承抽象类类似,只不过继承是在类的层面上操作,接口是在方法和常量集合的层面上操作,接口比抽象类更抽象.更简洁.可以把实现接口看成继承特定的一个或多个方法以及一些常量,关于接口的具体规则这里不赘述. 为什么要使用接口和抽

  • JavaScript中的回调函数实例讲解

    在JS中,函数可以作为参数传递给函数,不止可以传递值或者对象,案例如下: 定义: /** *@project: data_overnance *@package: *@date:2018/11/30 0030 15:07 *@author 郭宝 *@brief: 回调函数 */ export default class Person { constructor(){ } /** * 设置名称 * @param nameCallback 传入回调函数 */ setName(nameCallback

  • java中Path和ClassPath用法比较

    java中Path是什么? 在计算机上安装Java后,需要设置PATH环境变量以便从任何目录方便地运行可执行文件(javac.exe,java.exe,javadoc.exe等),而无需键入完整路径命令.[视频教程推荐:Java教程] 例如: C:\ javac TestClass.java 否则,您需要在每次运行时指定完整路径,例如: C:\ Java \ jdk1.7.0 \ bin \ javac TestClass.java java中和ClassPath是什么? Classpath是J

  • java使用三层架构实现电影购票系统

    使用三层架构实现电影购票系统,分用户和管理员,用户功能:展示电影,查找电影(模糊查询),查看电影详情,查找场次,购买影票,订制座位,退订影票等功能,界面美观漂亮,逻辑严谨,附加电影评论功能,订票超过五张打0.9折的打折功能.管理员功能:影院的增删改查,场次的增删改查,电影的增删改查,影票管理等. 管理员账号:admin  密码:admin 下载地址:java实现电影购票系统 效果展示图: 登录界面: 用户主界面: 查看热门电影: 点击电影进入查看详情,可以看到该电影的所有评论,可以进行评论. 点

  • Java中的接口回调实例

    定义: /** * @author Administrator * @project: TestOne * @package: PACKAGE_NAME * @date: 2018/11/30 0030 15:42 * @brief: 郭宝 **/ public class Person { /** * 自定义一个接口 **/ public interface OnNameChangeListener{ //接口中的抽象函数,并携带数据 void onNameChange(String name

  • JavaScript私有变量实例详解

    本文实例讲述了JavaScript私有变量.分享给大家供大家参考,具体如下: 任何在函数中定义的变量,就是私有变量,因为这些变量在函数外部是无法访问到的.总的来说,私有变量包括函数的参数.局部变量和在函数内部定义的其他函数. function add(num1, num2){ var sum = num1 + num2; return sum; } 上面的例子中的 num1, num2, sum 就是函数的私有变量. 如果在这个函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问这些变量,

  • java 接口回调实例详解

    java 接口回调实例详解 首先官方对接口回调的定义是这样的,所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法.这样听起来有点绕,我们可以这么理解接口回调:比如我们想知道隔壁老王啥时候回家?但是我们有自己的事情做不能一直监视着老王,那么我们可以雇员小区的保安来完成这个任务,当老王回家口,保安就给我们打电话告诉我们,老王回来了!这样就完成了一个事件的传递: 首先我们定义了一个接口: public interface DynamicMessage

  • Java在运行时识别类型信息的方法详解

    前言 在日常的学习工作当中,有一些知识是我们在读书的时候就能够习得:但有一些知识不是的,需要在实践的时候才能得到真知--这或许就是王阳明提倡的"知行合一". 在Java中,并不是所有的类型信息都能在编译阶段明确,有一些类型信息需要在运行时才能确定,这种机制被称为RTTI,英文全称为Run-Time Type Identification,即运行时类型识别,有没有一点"知行合一"的味道?运行时类型识别主要由Class类实现. 01 Class类 在Java中,我们常用

随机推荐