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

   今天提到的“抽象接口”,就是用来解决这个问题的。   为了不误导读者,先说明一下,什么是“抽象接口”。   所谓“抽象接口”,即在提供接口的同时,提供一个抽象类,用抽象类实现该接口(实际上这是缺省适配模式)。   下面举个例子,让读者体会这样做的好处。   代码写的不咋地,为了防止读者看不懂,先上一张类图:

在这里插入图片描述

具体代码:

  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子类没有直接实现接口,而是通过继承抽象类间接实现接口,这样好处一下就体现出来了!

    向接口中新增的方法,可以在实现接口的抽象类中缓冲一下,提供一个默认的实现,这样一来,就不必强制所有的子类(通过继承抽象类间接实现接口的类)都进行修改,可以形象的理解为“没有惊动子类”。而需要使用这个方法的子类,直接重写即可。
    image
最新2020整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友请加Q君样:909038429
/./*欢迎加入java交流Q君样:909038429一起吹水聊天

更多相关文章

  1. 【编测编学】接口测试面试题必背(上)
  2. Java 中的构造函数引用和方法引用
  3. 你的接口,真的能承受高并发吗?
  4. 压缩两个集合,方法原来这么多(实用技巧)
  5. 我在一个构造方法中写了30个参数,老板看了想骂人
  6. 在python中执行shell命令的6种方法
  7. 多线程学习(三)多线程开发带来的问题与解决方法

随机推荐

  1. Android学习笔记-Android简介
  2. Android 基本控件Text属性
  3. Android 安全加密:Https编程详解
  4. android基础知识15:获得android系统信息02
  5. android转屏时数据保存问题
  6. Android 从初学者入门到成为高手 视频教
  7. Android当中layer-list使用来实现多个图
  8. Android之Button按钮
  9. android sqlite 简明教程
  10. 修改光标颜色