zoukankan      html  css  js  c++  java
  • Java抽象接口技巧(一)

    原文链接 http://blog.csdn.net/qq_35101189/article/details/70799155

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

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

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

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

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

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

    具体代码:

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

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

  • 相关阅读:
    web服务器-Apache
    nginx优化
    nginx下载限速
    nginx-URL重写
    HDU 5358 First One 求和(序列求和,优化)
    HDU 5360 Hiking 登山 (优先队列,排序)
    HDU 5353 Average 糖果分配(模拟,图)
    UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
    HDU 5348 MZL's endless loop 给边定向(欧拉回路,最大流)
    HDU 5344 MZL's xor (水题)
  • 原文地址:https://www.cnblogs.com/jdhdevelop/p/6768485.html
Copyright © 2011-2022 走看看