从单元测试的角度看,抽象类与接口有很大区别;下面将会提到,即使有了抽象类,也应该做一个接口。
为什么这么说呢?我们都知道单元测试时往往需要Mock一个被依赖的接口,并且要实现这个接口中的相关方法。
举例来说,如果我们要测A类,而A调用了B.method1(),那我们的Mock类就要实现B接口,并实现method1()方法
但如果被B不是一个接口名,而是一个无接口的具体类(也就是说没有按接口编程),那也不难办,我们就继承B,并覆盖method1()方法,可能还要覆盖构造方法,如果B中的构造方法依赖了别的资源。 这样做已经有点别扭了。
但如果B是一个抽象类,那就更别扭了。因为你不但要覆盖B的method1()方法和B的构造方法,还要实现B的抽象方法!不过,如果B的抽象方法就是method1(),那就不必了。
那么从中可以看出抽象类与接口的什么区别呢? 区别就是
接口的抽象方法代表真正的契约,而抽象类中的就未必。接口中的抽象方法总是为他人服务的public方式,而抽象类中的抽象方法可能只是protected的,交给子类实现而已。
再进一步说,
接口和抽象类都体现了一种抽象,一种等待子孙来实现的抽象;但接口还代表了一项服务。
而单元测试时的Mock是对服务的一种Mock,显然,这时候我们更偏好接口。