接口和抽象类比较

1 相同点:

1)都不能实例化,就是类不能new一个对象。

2)接口的实现类或抽象类的的子类都只有实现接口或抽象中      的方法才能被实例化

1不同点

1)接口里只有定义,方法体不能在接口里实现   /   抽象类可以有定义与实现,被声明为抽象的方法不能有方法体,没有声明为抽象的方法可以有方法体。

2)接口需要实现(implements),抽象类只能被继承(extends)

3)接口里的方法都是抽象的,抽象类只要有一个抽象类的方法就可以。

4)总的来说,接口被运用于实现比较常用的功能,便于日后维护或者删除方法/ 而抽象类更倾向充当公共类的角色,不适于日对里面代码进行修改。

我们看一个银行借款的领子,中国人民银行管理并监督所有的银行,它制定了一个规范,所有的银行在进行借款时都必须遵守这个规范(基本接口);

Version~0.1.0:

中国人民银行定义了一个操作接口:

  1. package GoodDesignPattern;
  2. import java.util.Map;
  3. public interface BankLoan {
  4. /**
  5. * 银行借款操作
  6. * 每个公司都需要实现该方法,并针对自己公司员工的情况进行特殊操作,
  7. * 比如判断该员工是否有资格,能借款多少等等
  8. * @return
  9. */
  10. public Map<String, String> loanOperation(String userId);
  11. }

所有的银行都必须遵守这个接口,进行具体的实现:

  1. package GoodDesignPattern;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class ABC implements BankLoan {
  5. @Override
  6. public Map<String, String> loanOperation(String userId) {
  7. //所有银行借款必须的校验
  8. if(userId== null || userId.isEmpty()){
  9. System.out.println( "userId为空!");
  10. return null;
  11. }
  12. //所有银行借款必须的校验
  13. if(userId.length()!= 32){
  14. System.out.println( "userId格式错误,应该为32位!"+userId);
  15. return null;
  16. }
  17. //所有银行借款必须的校验
  18. if(!queryUserExist(userId)){
  19. System.out.println( "用户不存在:"+userId);
  20. return null;
  21. }
  22. //所有银行借款必须的校验
  23. if(!queryUserIllegal(userId)){
  24. System.out.println( "用户没有资格进行借款:"+userId);
  25. return null;
  26. }
  27. //业务逻辑
  28. Map<String, String> map = getResultMap(userId);
  29. return map;
  30. }
  31. //根据数据库查询是否存在,根据自己公司的用户表查询
  32. public boolean queryUserExist(String userId){
  33. return true; //return false;
  34. }
  35. //根据数据库查询数据查询判断
  36. public boolean queryUserIllegal(String userId){
  37. return true; //return false;
  38. }
  39. //根据数据库查询相关信息
  40. public Map<String, String> getResultMap(String userId){
  41. Map<String, String> map = new HashMap<String, String>();
  42. map.put( "name", "詹姆斯"); //此处为了方便直接写死
  43. map.put( "amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死
  44. map.put( "rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死
  45. //.....其它一些列操作
  46. return map;
  47. }
  48. }

  1. package GoodDesignPattern;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class ICBC implements BankLoan {
  5. @Override
  6. public Map<String, String> loanOperation(String userId) {
  7. //所有银行借款必须的校验
  8. if(userId== null || userId.isEmpty()){
  9. System.out.println( "userId为空!");
  10. return null;
  11. }
  12. //所有银行借款必须的校验
  13. if(userId.length()!= 32){
  14. System.out.println( "userId格式错误,应该为32位!"+userId);
  15. return null;
  16. }
  17. //所有银行借款必须的校验
  18. if(!queryUserExist(userId)){
  19. System.out.println( "用户不存在:"+userId);
  20. return null;
  21. }
  22. //所有银行借款必须的校验
  23. if(!queryUserIllegal(userId)){
  24. System.out.println( "用户没有资格进行借款:"+userId);
  25. return null;
  26. }
  27. //业务逻辑
  28. Map<String, String> map = getResultMap(userId);
  29. return map;
  30. }
  31. //根据数据库查询是否存在,根据自己公司的用户表查询
  32. public boolean queryUserExist(String userId){
  33. return true; //return false;
  34. }
  35. //根据数据库查询数据查询判断
  36. public boolean queryUserIllegal(String userId){
  37. return true; //return false;
  38. }
  39. //根据数据库查询相关信息
  40. public Map<String, String> getResultMap(String userId){
  41. Map<String, String> map = new HashMap<String, String>();
  42. map.put( "amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死
  43. map.put( "rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死
  44. //.....其它一些列操作
  45. return map;
  46. }
  47. }
我们发现,每当一家银行做此操作时,都会做一些校验,并且他们都是类似的,这不仅繁琐,而且有些银行容易遗漏一些校验操作;虽然校验的逻辑大同小异,但是每个银行都可能自己定义自己的方法名、判断自己的业务逻辑,这样的开发低效且中国人民银行不方便管理,为此,人行需要调整自己的规范,统一各个银行的行为;

Version~0.2.0:

中国人民银行修改自己的规范:

之前的接口不变,新增一个抽象类:

  1. package GoodDesignPattern;
  2. import java.util.Map;
  3. public abstract class CommonOpretion {
  4. public Map<String, String> loanOperation(String userId) {
  5. //所有银行借款必须的校验
  6. if(userId== null || userId.isEmpty()){
  7. System.out.println( "userId为空!");
  8. return null;
  9. }
  10. //所有银行借款必须的校验
  11. if(userId.length()!= 32){
  12. System.out.println( "userId格式错误,应该为32位!"+userId);
  13. return null;
  14. }
  15. //所有银行借款必须的校验
  16. if(!queryUserExist(userId)){
  17. System.out.println( "用户不存在:"+userId);
  18. return null;
  19. }
  20. //所有银行借款必须的校验
  21. if(!queryUserIllegal(userId)){
  22. System.out.println( "用户没有资格进行借款:"+userId);
  23. return null;
  24. }
  25. //业务逻辑
  26. Map<String, String> map = getResultMap(userId);
  27. return map;
  28. }
  29. //根据数据库查询是否存在,根据自己公司的用户表查询
  30. protected abstract boolean queryUserExist(String userId);
  31. //根据数据库查询数据查询判断
  32. protected abstract boolean queryUserIllegal(String userId);
  33. //根据数据库查询相关信息
  34. protected abstract Map<String, String> getResultMap(String userId);
  35. }
看看这个抽象类的逻辑,你可以看出来,把所有的公共逻辑都写在里面,具体的业务操作方法是抽象的,由具体的银行去实现即可,看下银行的实现:

  1. package GoodDesignPattern;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class ABC extends CommonOpretion implements BankLoan {
  5. //根据数据库查询是否存在,根据自己公司的用户表查询
  6. @Override
  7. public boolean queryUserExist(String userId){
  8. return true; //return false;
  9. }
  10. //根据数据库查询数据查询判断
  11. @Override
  12. public boolean queryUserIllegal(String userId){
  13. return true; //return false;
  14. }
  15. //根据数据库查询相关信息
  16. @Override
  17. public Map<String, String> getResultMap(String userId){
  18. Map<String, String> map = new HashMap<String, String>();
  19. map.put( "name", "詹姆斯"); //此处为了方便直接写死
  20. map.put( "amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死
  21. map.put( "rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死
  22. //.....其它一些列操作
  23. return map;
  24. }
  25. }

  1. package GoodDesignPattern;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class ICBC extends CommonOpretion implements BankLoan {
  5. //根据数据库查询是否存在,根据自己公司的用户表查询
  6. @Override
  7. public boolean queryUserExist(String userId){
  8. return true; //return false;
  9. }
  10. //根据数据库查询数据查询判断
  11. @Override
  12. public boolean queryUserIllegal(String userId){
  13. return true; //return false;
  14. }
  15. //根据数据库查询相关信息
  16. @Override
  17. public Map<String, String> getResultMap(String userId){
  18. Map<String, String> map = new HashMap<String, String>();
  19. map.put( "amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死
  20. map.put( "rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死
  21. //.....其它一些列操作
  22. return map;
  23. }
  24. }
每个银行只要继承这个抽象类,并实现对应的业务逻辑方法即可,一些校验都统一放入抽象类中判断,这样,每个银行的实现逻辑清晰、规范、不会遗漏校验,当然如果抽象类中的某些抽象方法,有些银行不想做具体实现,可以默认返回,当然这是一个缺陷,欢迎读者提出更好的解决方案。

这个时候每个银行又要实现抽象类,又要实现接口,他们感觉很麻烦且没有必要,这个时候中国银行又进行调整:

Version~0.3.0:
顶层接口还是不变,抽象类修改:由抽象类实现接口

  1. package GoodDesignPattern;
  2. import java.util.Map;
  3. public abstract class CommonOpretion implements BankLoan{
  4. @Override
  5. public Map<String, String> loanOperation(String userId) {
  6. //所有银行借款必须的校验
  7. if(userId== null || userId.isEmpty()){
  8. System.out.println( "userId为空!");
  9. return null;
  10. }
  11. //所有银行借款必须的校验
  12. if(userId.length()!= 32){
  13. System.out.println( "userId格式错误,应该为32位!"+userId);
  14. return null;
  15. }
  16. //所有银行借款必须的校验
  17. if(!queryUserExist(userId)){
  18. System.out.println( "用户不存在:"+userId);
  19. return null;
  20. }
  21. //所有银行借款必须的校验
  22. if(!queryUserIllegal(userId)){
  23. System.out.println( "用户没有资格进行借款:"+userId);
  24. return null;
  25. }
  26. //业务逻辑
  27. Map<String, String> map = getResultMap(userId);
  28. return map;
  29. }
  30. //根据数据库查询是否存在,根据自己公司的用户表查询
  31. protected abstract boolean queryUserExist(String userId);
  32. //根据数据库查询数据查询判断
  33. protected abstract boolean queryUserIllegal(String userId);
  34. //根据数据库查询相关信息
  35. protected abstract Map<String, String> getResultMap(String userId);
  36. }
具体银行不再需要实现接口:

  1. package GoodDesignPattern;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class ABC extends CommonOpretion {
  5. //根据数据库查询是否存在,根据自己公司的用户表查询
  6. @Override
  7. public boolean queryUserExist(String userId){
  8. return true; //return false;
  9. }
  10. //根据数据库查询数据查询判断
  11. @Override
  12. public boolean queryUserIllegal(String userId){
  13. return true; //return false;
  14. }
  15. //根据数据库查询相关信息
  16. @Override
  17. public Map<String, String> getResultMap(String userId){
  18. Map<String, String> map = new HashMap<String, String>();
  19. map.put( "name", "詹姆斯"); //此处为了方便直接写死
  20. map.put( "amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死
  21. map.put( "rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死
  22. //.....其它一些列操作
  23. return map;
  24. }
  25. }
到此一个体现接口和抽象类结合使用的简单例子就说完了,谢谢~
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值