java中,允许单继承、多接口实现;继承不一定要重写所有父类方法,且能创建新方法,抽象类的抽象方法必须被实现它的子类实现除非子类也是抽象类,而接口方法默认有final static修饰,实现类必须实现所有方法。
很多小程序中似乎写接口体现不出价值,甚至要用啥旁边加个功能方法就够用;学习的SSH的web项目中倒是用到接口,在dao、biz(service)层中定义,在impl层实现,但现在看来实现层与定义层也是一一对应,并没有多实现的地方。
其实在业务逻辑层是用到多态了的,不使用框架时这里创建dao层实例是
XxxDao xxxDao = new XxxDaoImpl();
这里引用是接口的引用,实例却是实现类的实例,也就是说如果XxxDao接口有更多的实现,比如YyDaoImpl,那么用Yy里的方法时是可以且需要
XxxDao yyDao = new YyDaoImpl();
的,比如XxxDao接口定义了方法
void abc();
在XxxDaoImpl、YyDaoImpl分别有不同实现,这里就可以
xxxDao.abc();
yyDao.abc();
来使用各自的实现方法。但继承也可以做到,因为这里XxxDaoImpl、YyDaoImpl都只实现XxxDao一个接口,一个的话继承当然也做的来,这里就是因为约定俗成的规范而使用接口来实现。
当XxxDaoImpl、YyDaoImpl实现的是多个接口时,就只能用接口来做了。
举个例子,
Dao层:
SaveDao接口定义储存方法 void save(Xxx xxx);
FindAllDao接口定义查找所有方法 List<Xxx> findAll();
FindByConditionDao接口定义条件查询方法 List<Xxx> findByCondition(Map<String,String> queryMap);
那么按学校教的DaoImpl层:
SaveDaoImpl类实现SaveDao的void save(Xxx xxx){...}
FindAllDaoImpl类实现FindAllDao的List<Xxx> findAll(){...;return list;}
FindByConditionDaoImpl类实现FindByConditionDao的List<Xxx> findByCondition(Map<String,String> map){...;return list;}
现在看来可以合并后俩:
SaveDaoImpl类实现SaveDao的void save(Xxx xxx){...}
FindDaoImpl类实现FindAllDao、FindByConditionDao两个接口,内含两个方法:List<Xxx> findAll(){...;return list;}和List<Xxx> findByCondition(Map<String,String> map){...;return list;}
那么在biz(service)层就分别是:
1
SaveDao saveDao = new SaveDaoImpl();
FindAllDao findAllDao = new FindAllDaoImpl();
FindByConditionDao findByConditionDao = new FindByConditonDaoImpl();
saveDao.save(xx);
List<Xxx> xxxList = findAllDao.findAll();
xxxList = findByConditionDao.findByCondition(map);
2
SaveDao saveDao = new SaveDaoImpl();//不变
FindDao findDao = new FindDaoImpl();//合并查找的实现后只需要一个接口引用
saveDao.save(xx);
List<Xxx> xxxList = findDao.findAll();
xxxList = findDao.FindByCondition(map);
save是单实现,看起来用继承也没问题,两个查找的合并就只能用接口实现了,为了避免后者的情况,统一用接口定义此类方法。
接口的好处除了这样归类,还有就是方便分工,比如这里架构写了接口,两种查询的具体实现可由其他两人各自完成
------------------------------
其实以上例子只用到了同一类对多个接口的多实现,所谓的方便分工还包括不同类对同一接口的不同方法的实现,
比如FindDao接口中有findAll、findByCondition两个方法,这里有若干个表,比如学生表、成绩表,那么就可以在接口中去掉返回值的泛型,然后在DaoImpl层:
FindStudentDaoImpl类,...findAll(){String sql="select * from STUDENT";...} ...findByCondition(Map<String,String> map){String sql = "select * from STUDENT where..."...}
FindGradeDaoImpl类,...findAll(){...select * from GRADE...}...findByCondition(...){...select * from GRADE...}
biz层在查询学生、成绩时就是:
FindDao findStudentDao = new FindStudentDaoImpl();
FindDao findGradeDao = new FindGradeDaoImpl();
findStudentDao.findAll();//学生表
findGradeDao.findAll();//成绩表
或者用同一个引用也可以,反正都是FindDao接口的引用,不过要在用完一个实现后再赋另一个实现:
FindDao findDao = new FindStudentDaoImpl();
findDao.findAll()//学生表
findDao = new FindGradeDaoImpl();
findDao.findAll();//成绩表
SaveDao的话继承当然也做得到,但FindDao这样的就只能用该接口了。以上