不知道其他人是否有这样的疑惑,做了很久的java开发,对于接口和抽象类的语法使用也是了如指掌。但似总觉得对它没有彻底的搞明白,比如,笔者就有这样的疑惑:
1.接口和抽象类都是作为抽象来使用的,为什么不单独使用接口或者单独使用抽象类?两者都存在的意义是什么?
2.一个类为什么可以实现多个接口而不能继承多个抽象类?
3.对于一个具体的业务,该使用接口还是该使用抽象类?
里面有这么一段:
InterfacesinJava
IntheJavaprogramminglanguage,aninterfaceisareferencetype,similartoaclass,thatcancontainonlyconstants,methodsignatures,defaultmethods,staticmethods,andnestedtypes.Methodbodiesexistonlyfordefaultmethodsandstaticmethods.Interfacescannotbeinstantiated—theycanonlybeimplementedbyclassesorextendedbyotherinterfaces.Extensionisdiscussedlaterinthislesson.
谷歌翻译过来大概是:在Java编程语言中,一个接口是一个引用类型,类似于类,它只可以包含常量,方法签名,默认的方法,静态方法和嵌套类型。方法主体仅适用于默认方法和静态方法。接口无法实例化-它们只能由类实现或由其他接口扩展。
上面概念比较笼统,结合笔者经验,一步步将接口的使用方法用下面代码展示,为了时例子具有说明性,就以jdk自带的集合来说明。
2.1接口的定义
接口定义比较简单,只需要interface关键字即可,如Map集合。List集合等。
2.2接口中方法的定义:
返回值类型+方法名(参数。。。),例如,List集合的方法。并且,方法是没有方法体的。即只能生命方法,不能实现方法。
以上是规范的定义方式,官方规定,方法必须定义成public或abstract形式,且是默认的。可以用一个测试例子看下哪些是不规范的,如下:
idea编译器会将无用的代码置为灰色,如上图,从图中可以看出,public和abstract是可以省略的,且很多公司规则必须省略,如果将方法定义成private或者protected会直接语法报错。对于方法size3(),虽然语法没有报错,但是由于静态方法不能被重写这一特性,在接口中定义静态方法是没有实际意义的。
2.3接口中常量的定义
java规范:接口中不能定义变量,只能定义常量,格式:publicstaticfinal数据类型常量名称(大写)=数据值;且必须赋初始值。publicstaticfinal可省略。如下:
如上图,由于接口中只能定义常量,所以必须赋初始值,不赋值,会报错。且publicstaticfinal可省略。
2.4接口的实现:implements、extends
(1)普通类实现接口
如上,HashSet类实现Set接口,使用implements关键字,需重写接口中的所有方法,包括接口父接口的所有方法。上面HsahSet接口实现了Set接口中的所有方法和Coneable接口中的所有方法。如果Set接口和Coneable接口有相同的方法,只需要重写一个。
(2)接口实现接口
接口实现接口需要使用extends关键字,不能使用implements。
抽象类实现接口,可以重写接口中的方法,但不是必须重写。使用关键字implements。相反,抽象类是不能被接口继承的,因为,抽象类可以有具体的方法体,而接口不能。
描述:
AbstractMethodsandClasses
Anabstractclassisaclassthatisdeclaredabstract—itmayormaynotincludeabstractmethods.Abstractclassescannotbeinstantiated,buttheycanbesubclassed.
Anabstractmethodisamethodthatisdeclaredwithoutanimplementation(withoutbraces,andfollowedbyasemicolon)
这个描述比较模糊,下面详细说明。
下面以javaIO流的源码展示。
2.1抽象类的定义
定义只需要在普通类中增加abstract关键字即可。或者只要有抽象方法的类,肯定是抽象类。
2.2抽象类方法的定义
抽象类中定义抽象方法,必须加关键字abstract,并且方法没有方法体。构造方法和静态方法(类方法)不能定义为抽象方法。访问类型可以是public,protected,并且默认是publicabstract类型。
抽象类中定义普通方法,必须有方法体,和普通类中的方法定义一致。
2.3常量和变量的定义
抽象类和普通类在定义常量和变量没有什么区别,如下图:
2.4抽象类的继承
抽象类可以实现接口
如上图,为Reader类对Readable和Closeable接口的实现。抽象类实现接口,不必重写接口中的方法,但是,抽象类的子类必须重写接口以及抽象类中的抽象方法。