作者:林子云
链接:https://www.zhihu.com/question/36909455/answer/298159409
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
一 接口与抽象类的语法上区别
1.1)接口都是抽象方法,而抽象类中既可以有抽象方法,也可以有(实例)instance 方法。
1.2)接口中的变量都是 public static final 而抽象类中的变量可以被任何通用修饰符修饰。
1.3)一个类可以实现多个接口,但是只能继承一个抽象类。
- 抽象类继承接口,可实现也可不实现接口中定义的方法
- 如果抽象类中实现了 → 抽象类的子类可不用实现,但需要实现抽象类中定义的接口(如果有的话),也可重写覆盖抽象类的方法
- 如果抽象类中没有实现,则子类需要实现接口
二 接口与抽象类的涵义上区别
2.1)接口定义的是所有实现类必须实现的规则,是一种承诺和约束,保证所有的实现类都有相关的方法可供调用;
而抽象类更多的是对通用的、基础的方法封装,让子类复用,避免在子类开发重复的代码。子类只需实现抽象方法,也可以有选择的覆盖抽象父类的方法。
三 实践
3.1)将依赖的、通用的对象放到Abstract的基类中,减少重复代码。
例如各种数据库 manager,service,logger 等,并设置成 protect 级别。
3.2)将通用工具代码、业务代码放到基类中可供不同子类调用。
比如,parseData(),getLong(),str2Long() 之类的。
3.3)制定类的处理流程,封装通用功能代码,让子类按照某种流程来处理。
比如,基类中定义一个 abstract 的 subExecute(),在基类中,可以先检查入参,查询相关数据,做一些其他业务事情,然后执行subExecute()。在外面统一处理异常。
3.4)场景举例demo。商家要管理活动,可以创建和修改活动数据,由不同的类来完成。
public interface ActivityManager {public Result process(Param param)}public abstract class BaseActivityManager implement ActivityManager {// 定义成 protect,子类可以访问到protect Logger logger = xxxLogger;@Autowiredprotected UserManager userManager;@Autowiredprotected ItemManager itemManager;public abstract Result subProcess(Param param);//定义子类处理流程public Result process(Param param) {try{//入参检查checkParam(param);//用户登录检查checkLogin(param);//活动权限检查,商家是否能管理该活动checkRole(param)//操作日志记录operationLog(param);//其他业务逻辑doOtherBiz(param);//最后执行操作return subProcess(Param param);}catch() {//记录异常log(e)}}}public class AddActivityManager extends BaseActivityManager {Result subProcess(Param param) {//todo}}public class EditActivityManager extends BaseActivityManager {Result subProcess(Param param) {//todo}}
当也可以在抽象类中不实现接口定义的方法,只是提供一些公共方法的封装,子类继承抽象类,去实现接口的时候,调用 super.xxx 方法(即抽象类中封装的方法)。
