设计模式之美 -- 接口和抽象类区别
抽象类
抽象类不允许被实例化,只能被继承。也就是说,你不能 new 一个抽象类的对象出来,会报编译错误。
抽象类可以包含属性和方法。方法既可以包含代码实现,也可以不包含代码实现。不包含代码实现的方法叫作抽象方法。
子类继承抽象类,必须实现抽象类中的所有抽象方法
接口
接口不能包含属性(也就是成员变量)。
接口只能声明方法,方法不能包含代码实现。
类实现接口的时候,必须实现接口中声明的所有方法。
java 语法:可以定义静态方法、default 方法,枚举类型,接口中还可以定义接口(嵌套)
抽象类和接口区别
相对于抽象类的 is-a 关系来说,接口表示一种 has-a 关系,表示具有某些功能。对于接口,有一个更加形象的叫法,那就是协议(contract)。抽象类更多的是为了代码复用,而接口就更侧重于解耦。接口是对行为的一种抽象,相当于一组协议或者契约,你可以联想类比一下 API 接口。调用者只需要关注抽象的接口,不需要了解具体的实现,具体的实现代码对调用者透明。接口实现了约定和实现相分离,可以降低代码间的耦合性,提高代码的可扩展性。
从类的继承层次上来看,抽象类是一种自下而上的设计思路,先有子类的代码重复,然后再抽象成上层的父类(也就是抽象类)。而接口正好相反,它是一种自上而下的设计思路。我们在编程的时候,一般都是先设计接口,再去考虑具体的实现。
为什么要用抽象类,普通类作为基类被继承不行吗?
目的是为了优雅实现多态,发生误用时,编译期就能发现。
强制子类重写基类的方法,忘记实现时,编译期就能发现(如果是普通类,编译器会认为要调用的是基类的方法)。
如果不用抽象类,基类的方法都要定义成一个空方法,语义上不优雅,且容易造成误用(new 一个基类,随意调用里面的方法,当然可以定义私有构造函数来避免,但是没那么优雅)
评论