博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中的“抽象接口”
阅读量:3659 次
发布时间:2019-05-21

本文共 3663 字,大约阅读时间需要 12 分钟。

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

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

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

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

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

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

具体代码:

  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://huafn.baihongyu.com/

你可能感兴趣的文章
TypeScript从入门到精通(一)准备工作
查看>>
TypeScript从入门到精通(二)静态类型
查看>>
排序算法学习和总结
查看>>
缓存优化
查看>>
Java内存模型vs JVM运行时数据区
查看>>
工作内存缓存问题
查看>>
对于同步的规则定义
查看>>
ReentrantLock(可重入锁)
查看>>
ReadWriteLock(读写锁)
查看>>
HashMap的实现原理
查看>>
Ansible 角色:安装mysql(简易版)
查看>>
Ansible: 安装与配置
查看>>
显示调用panic函数
查看>>
数组越界导致panic
查看>>
recover的使用
查看>>
字符串操作常用函数介绍
查看>>
字符串操作代码验证
查看>>
字符串转换
查看>>
正则表达式(上)
查看>>
json介绍
查看>>