在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现。

今天小菜提到的“抽象接口”,就是用来解决这个问题的。

为了不误导读者,先说明一下,什么是“抽象接口”。

所谓“抽象接口”,即在提供接口的同时,提供一个抽象类,用抽象类实现该接口(实际上这是缺省适配模式)。

下面小菜举个例子,让读者体会这样做的好处。

代码写的不咋地,为了防止读者看不懂,先上一张类图:

具体代码:

  ITestInterface.java

1 /*
2     假设有一个顶层接口
3 */ 4 public interface ITestInterface{ 5 void method1(); 6 int method2(); 7 boolean method3(); 8 }

  TestAbstract.java

 1 /*
 2     抽象类abstract实现了ITestInterface顶层接口
 3 */  4  5 public abstract class TestAbstract implements ITestInterface{  6 //找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现  7 public abstract void method1();  8 public abstract int method2();  9 10 //一些独特的方法可以在抽象类中默认实现 11 public boolean method3(){ 12 return true; 13  } 14 }

  

  TestClass1.java

 1 /*
 2     普通类TestClass1继承了TestAbstract抽象类
 3 */  4  5 public class TestClass1 extends TestAbstract{  6  7 //TestClass1必须实现抽象的method1方法,该方法最早是接口中定义的  8 public void method1(){  9 10  } 11 //TestClass1必须实现抽象的method2方法,该方法最早是接口中定义的 12 public int method2(){ 13 return 1; 14  } 15 16 //接口中的method3方法对于TestClass1无关紧要,因此不做重写。 17 }

  TestClass2.java

 1 /*
 2     普通类TestClass2继承了TestAbstract抽象类
 3 */  4  5 public class TestClass2 extends TestAbstract{  6  7 //TestClass2必须实现抽象的method1方法,该方法最早是接口中定义的  8 public void method1(){  9 10  } 11 //TestClass2必须实现抽象的method2方法,该方法最早是接口中定义的 12 public int method2(){ 13 return 2; 14  } 15 16 //method3方法对于TestClass2来说至关重要,因此必须重写。 17 public boolean method3(){ 18 return false; 19  } 20 21 }

代码精讲:

    从以上例子可以看出,最高层的接口被一个抽象类实现,在抽象类中,我们把关键的method1、method2方法定义成抽象方法,强制子类去实现,而“独特”的method3方法在抽象类中做一个默认实现。

    等到TestClass1、TestClass2继承TestAbstract抽象类时,优势就体现出来了,TestClass1、TestClass2必须实现method1、method2,但如果用不到method3,可以直接无视。

    通过接口和抽象类的结合,避免了在实现接口的子类中出现大量的“无意义”实现,这个“无意义”实现,被缓冲到了抽象类中,完美展现了代码复用(可以把抽象类理解成接口和实现类之间的缓冲)。

    需要指出的是,我们既可以选择继承抽象类,也可以选择实现接口,并不是说一定要继承抽象类,看情况而定,这里是两种选择,两个机会。

写到这,或许读者觉得文章已经结束了,其实没有。。。

这样做的好处不仅仅是这一点,细细品味,假如我们向接口中增加了一个方法。。。

具体代码:

  温馨提示:不要被代码吓到,其实这些代码和上边的差不多,只不过加了个方法而已。

  ITestInterface.java

 1 /*
 2     假设有一个顶层接口
 3 */  4 public interface ITestInterface{  5 void method1();  6 int method2();  7 boolean method3();  8 //接口中新增加了方法  9  String method4(); 10 }

  TestAbstract.java

 1 /*
 2     抽象类abstract实现了ITestInterface顶层接口
 3 */  4  5 public abstract class TestAbstract implements ITestInterface{  6 //找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现  7 public abstract void method1();  8 public abstract int method2();  9 10 //一些独特的方法可以在抽象类中默认实现 11 public boolean method3(){ 12 return true; 13  } 14 15 //抽象类中提供一个默认实现,这样就可以避免"惊动"所有子类 16 public String method4(){ 17 return ""; 18  } 19 }

  TestClass1.java

 1 /*
 2     普通类TestClass1继承了TestAbstract抽象类
 3 */  4  5 public class TestClass1 extends TestAbstract{  6  7 //TestClass1必须实现抽象的method1方法,该方法最早是接口中定义的  8 public void method1(){  9 10  } 11 //TestClass1必须实现抽象的method2方法,该方法最早是接口中定义的 12 public int method2(){ 13 return 1; 14  } 15 16 //接口中的method3方法对于TestClass1无关紧要,因此不做重写。 17 18 //新增的方法对于TestClass1来说至关重要,因此必须重写 19 public String method4(){ 20 return "Class1"; 21  } 22 23 }

  TestClass2.java

 1 /*
 2     普通类TestClass2继承了TestAbstract抽象类
 3 */  4  5 public class TestClass2 extends TestAbstract{  6  7 //TestClass2必须实现抽象的method1方法,该方法最早是接口中定义的  8 public void method1(){  9 10  } 11 //TestClass2必须实现抽象的method2方法,该方法最早是接口中定义的 12 public int method2(){ 13 return 2; 14  } 15 16 //method3方法对于TestClass2来说至关重要,因此必须重写。 17 public boolean method3(){ 18 return false; 19  } 20 21 //新增的方法对于TestClass2来说无关紧要,无需知道新增method4的存在 22 }

代码精讲:

    这段代码演示了假如项目已经成型,但是需求有变,我们不得不向接口中增加一个新的方法,假如子类直接实现了接口,那么这些子类都要修改,来实现接口新增的方法。

    但本例中的TestClass1、TestClass2子类没有直接实现接口,而是通过继承抽象类间接实现接口,这样好处一下就体现出来了!

    向接口中新增的方法,可以在实现接口的抽象类中缓冲一下,提供一个默认的实现,这样一来,就不必强制所有的子类(通过继承抽象类间接实现接口的类)都进行修改,可以形象的理解为“没有惊动子类”。而需要使用这个方法的子类,直接重写即可。

小菜感慨:

    人类的智慧真伟大!数组和链表结合,产生了高效的哈希表;接口和抽象类结合,产生了优雅的缺省适配模式。大家努力吧!!!

写在后面的话:

    世间没有完美的事物,设计模式也是如此,过多的讨论优缺点没有意义,合适的就是最好的,什么是合适的呢?这才是体现智慧的地方。

来源:http://www.cnblogs.com/iyangyuan/archive/2013/03/11/2954808.html

转载于:https://www.cnblogs.com/ihanliu/p/4366468.html

JAVA中的“抽象接口”相关推荐

  1. Java中抽象类和接口在概念、语法和应用上的区别和关系

    2019独角兽企业重金招聘Python工程师标准>>> 春招开始了,盆友们都忙着准备笔试.准备面试,复习学过的知识点,当然我也不例外,在这里祝每一个"有心人"心想 ...

  2. 关于Java中抽象类和接口的一点思索

    Java中抽象类和接口的一点思索 成员方法上的区别: 1. java中的抽象类可以提供成员方法的实现细节,抽象方法只能是被public和protected来修饰 配合abstract关键字,子类需要实 ...

  3. Java中的某些接口为什么没有任何方法?

    java中,有些接口内部没有声明任何方法,也就是说,实现这些接口的类不需要重写任何方法. 这些没有任何方法声明的接口又被叫做标识接口.标识接口对实现它的类没有任何语义上的要求,仅仅充当标识的作用,用来 ...

  4. 简单学习Java中的抽象语法树(AST)

    概述 抽象语法树(AST)是一种数据结构,代表了一种编程语言的抽象语法.它通常在编译器中用来解析源代码和生成机器代码. 在Java中,AST通常由一个解析器创建,该解析器读取源代码并创建一个树状结构, ...

  5. Java中的Type接口和Class类区别和联系

    Java中的Type接口和Class类有什么区别 Type是Class的父接口. Type 是 Java 编程语言中所有类型的公共高级接口.它们包括原始类型.参数化类型.数组类型.类型变量和基本类型. ...

  6. java 抽象接口_JAVA中的“抽象接口”

    在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现. 今 ...

  7. Java中继承、接口、多态的作用详解(纯理论)

    一.继承.接口与多态的相关问题: 1. 继承的作用?好处?坏处? 继承:通过继承实现代码复用.Java中所有的类都是通过直接或间接地继程java.lang.Object类得到的.继承而得到的类称为子类 ...

  8. Java 中抽象类与接口

    Java 抽象类: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这个类就是抽象类. 抽象类不能创 ...

  9. Java中抽象类和接口

    一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的实现.抽象方法的声明格式为: 1 abstract void fun(); 抽象方法必须用abst ...

最新文章

  1. RocketMQ 基本概念
  2. 云服务器适合什么样的用户?
  3. LeetCode 1108. Defanging an IP Address--C++,Python解法
  4. 2017android开发找不到工作,揭秘蒋多多2017生活现状,30岁找不到工作曾绝望自杀...
  5. java实现递归下降分析_使用递归实现检查未知层级目录中的文件-Java实用技能
  6. 统计学习方法之机器学习相关理论
  7. AS插件-Android Parcelable code generator.
  8. 【设计模式】分类和定义
  9. 关于go指针在方法or函数中这件事
  10. shell把mysql每句导出_shell实现,将mysql每个存储过程导出为单个文件_MySQL
  11. mysql哪些字段适合索引_(转)Mysql哪些字段适合建立索引
  12. [saiku] 使用 Apache Phoenix and HBase 结合 saiku 做大数据查询分析
  13. xadmin在Django 1.11中的使用及中英文切换
  14. spring框架_Spring框架
  15. 数据挖掘导论完整版pdf中文
  16. 公司要一个网站,是选模板建站还是定制化建站?
  17. ORA-20001: Latest xml inventory is not loaded into table
  18. Anomaly Detection with Partially Observed Anomalies译文
  19. Vue SEO 优化 使用 Vapper SSR 服务器渲染框架 搭建项目 新手教程
  20. android自定义秒表,Android实现的秒表计时器示例

热门文章

  1. android sqlite assets,使用GreenDao加载assets下sqlite数据库的示例
  2. java基本框架代码_Rxjava 源码系列 - 基础框架分析
  3. 如何让html标签不转义
  4. NYOJ67 - 三角形面积
  5. php语句过滤掉html标签_php过滤HTML标签、属性等正则表达式
  6. 数据挖掘决策树python_机器学习之决策树ID3(python实现)
  7. 计算机网络—数据链路层的流量控制与可靠传输机制(思维导图)
  8. HDU 4694: Important Sisters(支配树)
  9. 香农编码的 matlab 实现
  10. python opencv 利用分水岭算法实现对物体的分割 图文详细注释版 以分割官网提供的硬币为例