Muscleape个人总结:(这里的抽象接口是指:使用一个抽象类实现一个接口,是两部分结构)

使用一个抽象类直接实现接口,将接口中的方法区分为实现类必须要实现的和选择性实现的,其他需要实现接口的类型通过继承这个抽象类的方式实现接口,这样在具体的实现类中可以不用重写接口中用不到的方法,如果后期接口中新增加了方法,只需要在抽象类中重写新方法,具体的实现类需要使用该方法的才去重写该方法,其他的实现类可以不用做任何修改;

JAVA中的“抽象接口”(原博文名称)

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

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

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

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

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

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

具体代码:

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

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

小菜感慨:

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

写在后面的话:

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

【转载】JAVA中综合接口和抽象类实现的一种“抽象接口”的更多相关文章

  1. [转载]java中import作用详解

    [转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...

  2. Java中的集合(七)双列集合顶层接口------Map接口架构

    Java中的集合(七)双列集合顶层接口------Map接口 一.Map接口的简介 通过List接口,我们知道List接口下的集合是单列集合,数据存储是单列的结构.Map接口下是一个键值对(key-v ...

  3. Java中的集合(三)继承Collection的Queue接口

    Java中的集合(三)继承Collection的Queue接口 一.Queue介绍 Queue接口继承自Collection接口,是Java中定义的一种队列数据结构,元素是有序的(按插入顺序排序),先 ...

  4. [转载]Java中继承、装饰者模式和代理模式的区别

    [转载]Java中继承.装饰者模式和代理模式的区别 这是我在学Java Web时穿插学习Java设计模式的笔记 我就不转载原文了,直接指路好了: 装饰者模式和继承的区别: https://blog.c ...

  5. [转载]Java中异常的捕获顺序(多个catch)

    http://blog.sina.com.cn/s/blog_6b022bc60101cdbv.html [转载]Java中异常的捕获顺序(多个catch) (2012-11-05 09:47:28) ...

  6. Java中的集合(六)继承Collection的Set接口

    Java中的集合(六)继承Collection的Set接口 一.Set接口的简介 Set接口和List接口都是继承自Collection接口,它与Collection接口中功能基本一致,并没有对Col ...

  7. Java中的集合(五)继承Collection的List接口

    Java中的集合(五)继承Collection的List接口 一.List接口简介 List是有序的Collection的,此接口能够精确的控制每个元素插入的位置.用户能够根据索引(元素在List接口 ...

  8. Java中创建(实例化)对象的五种方式

    Java中创建(实例化)对象的五种方式1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运用反 ...

  9. 如何在java中跳出当前多重嵌套循环?有几种方法?

    如何在java中跳出当前多重嵌套循环?有几种方法? - 两种方法   - 1.在外层循环定义标记          ok:          for(int i=0;i<100;i++){    ...

随机推荐

  1. 二:熟悉 TCP/IP 协议

    一篇文章带你熟悉 TCP/IP 协议(网络协议篇二) 同样的,本文篇幅也比较长,先来一张思维导图,带大家过一遍. 一图看完本文 一. 计算机网络体系结构分层 计算机网络体系结构分层计算机网络体系结构分 ...

  2. 逆向实战第一讲,寻找OllyDbg调试工具的Bug并修复

    逆向实战第一讲,寻找OllyDbg调试工具的Bug并修复 首先我们要知道这个OD的Bug是什么. 我们调试一个UNICODE的窗口,看下其窗口过程. 一丶查看OllyDbg 的Bug 1.1spy++ ...

  3. Python之元类

    类型对象负责创建对象实例,控制对象行为.那么类型对象又由谁来创建呢? 元类(metaclass)——类型的类型 New-Style Class的默认类型是type >>> class ...

  4. [标]ORACLE常用的一些语句记录

    --查询实际的统计信息select     num_rows,blocks,empty_blocks,avg_space,avg_row_len,sample_size, last_analyzed  ...

  5. 初窥 MongoDB

    最近在研究Nodejs 自然就接触到了MongoDB  这玩意儿有意思  与关系型数据库相比少了很多条条框框 让我情不自禁的想要了解它的所有 MongoDB与Redis同类 属于NoSql的一种,特点 ...

  6. Python 运行效率为何低

    当我们提到一门编程语言的效率时:通常有两层意思,第一是开发效率,这是对程序员而言,完成编码所需要的时间:另一个是运行效率,这是对计算机而言,完成计算任务所需要的时间.编码效率和运行效率往往是鱼与熊掌的 ...

  7. Heap Sorting 总结 (C++)

    各位读者,大家好. 因为算法和数据结构相关的知识都是在国外学的,所以有些词汇翻译的可能不准确,然后一些源代码的注释可能是英文的,如有给大家带来什么不方便,请见谅.今天我想写一下Heap相关的知识,从基 ...

  8. java基础回顾(一)

    java的特点:开源.安全.跨平台.简单易懂.一次编译可多处运行. JDK:java开发工具包 JDK = JRE+JAVA开发工具 保证能够实现java开发的最小单元 JRE:java运行环境 JR ...

  9. Windos系统git提交

    一.$ git status   //查看当前项目下所有文的状态,如果第一次,你会发现都红颜色的,因为它还没有交给git/github管理. 二.$ git add .   //(.)点表示当前目录下 ...

  10. 算法提高 9-3摩尔斯电码 map

    算法提高 9-3摩尔斯电码 时间限制:1.0s   内存限制:256.0MB     问题描述 摩尔斯电码破译.类似于乔林教材第213页的例6.5,要求输入摩尔斯码,返回英文.请不要使用"z ...