抽象类实现接口的默认适配器模式
来源:互联网 发布:司徒司空司马 知乎 编辑:程序博客网 时间:2024/05/07 01:29
今天小菜提到的“抽象接口”,就是用来解决这个问题的。
为了不误导读者,先说明一下,什么是“抽象接口”。
所谓“抽象接口”,即在提供接口的同时,提供一个抽象类,用抽象类实现该接口(实际上这是缺省适配模式)。
下面小菜举个例子,让读者体会这样做的好处。
代码写的不咋地,为了防止读者看不懂,先上一张类图:
具体代码:
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子类没有直接实现接口,而是通过继承抽象类间接实现接口,这样好处一下就体现出来了!
向接口中新增的方法,可以在实现接口的抽象类中缓冲一下,提供一个默认的实现,这样一来,就不必强制所有的子类(通过继承抽象类间接实现接口的类)都进行修改,可以形象的理解为“没有惊动子类”。而需要使用这个方法的子类,直接重写即可。
小菜感慨:
人类的智慧真伟大!数组和链表结合,产生了高效的哈希表;接口和抽象类结合,产生了优雅的缺省适配模式。大家努力吧!!!
写在后面的话:
世间没有完美的事物,设计模式也是如此,过多的讨论优缺点没有意义,合适的就是最好的,什么是合适的呢?这才是体现智慧的地方。
- 抽象类实现接口的默认适配器模式
- 接口声明-抽象类空实现-继承重写来实现适配器的模式
- 抽象类和接口的区别(里面有适配器设计、工厂设计、代理设计模式)
- 抽象类和接口的区别(里面有适配器设计、工厂设计、代理设计模式)
- 抽象接口类的实现(缺省适配模式)
- 策略模式接口和抽象类的简单实现
- 适配器模式(默认适配器)
- JavaLearning:适配器设计 接口和抽象类
- Java中的抽象类与接口以及类与接口间的适配器
- 抽象类实现多个接口与接口的继承的对比,实现良好的设计模式!
- 实现接口的抽象类的用处
- 基类 抽象类 设计模式-类适配器
- 适配器模式以及为什么允许声明没有抽象方法的类为抽象类?
- 接口的重实现与抽象类
- 抽象类实现接口的意义
- 抽象类、抽象方法、接口的区别及实现
- 默认适配器模式
- 默认适配器设计模式
- 【iOS面试】iOS面试经典题 NO.1
- Origin快速格式化Graph
- 【VMware记录】VMware Workstation 11.0试用
- opengl绘制多边形
- android自定义控件(二) 入门,继承View
- 抽象类实现接口的默认适配器模式
- 第十五周项目-指针当形参
- 第十五周项目三-在OJ上玩指针(4)
- 华为机试---字符串过滤
- Curl CA证书问题
- Lucene入门与介绍
- android自定义控件(三) 自定义属性
- 第十五周项目三——在OJ上玩指针(3)
- 第15周oj项目两个数由大到小输出