作者:林子云
链接: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;
@Autowired
protected UserManager userManager;
@Autowired
protected 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
方法(即抽象类中封装的方法)。