抽象类是一个声明为abstract
的类 — 它可能包括也可能不包括抽象方法,抽象类没法实例化,但能够进行子类化。html
抽象方法是在没有实现的状况下声明的方法(没有大括号,后跟分号),以下所示:java
abstract void moveTo(double deltaX, double deltaY);
若是一个类包含抽象方法,那么该类自己必须被声明为abstract
,如:segmentfault
public abstract class GraphicObject { // declare fields // declare nonabstract methods abstract void draw(); }
当抽象类被子类化时,子类一般为其父类中的全部抽象方法提供实现,可是,若是没有,那么子类也必须声明为abstract
。api
注意:未声明为default
或static
的接口(参见 接口部分)中的方法是隐式抽象的,所以abstract
修饰符不用于接口方法(能够使用,但不须要)。
抽象类与接口相似,你不能实例化它们,它们可能包含有或没有实现声明的方法的组合,可是,使用抽象类,你能够声明非静态和final
的字段,并定义public
、protected
和private
的具体方法。使用接口,全部字段都自动为public
、static
和final
,而且你声明或定义的全部方法(做为默认方法)都是public
,此外,你只能扩展一个类,不管它是不是抽象的,而你能够实现任意数量的接口。oracle
你应该使用哪一个,抽象类或接口?框架
若是任何这些语句适用于你的状况,请考虑使用抽象类:spa
protected
和private
)。若是任何这些语句适用于你的状况,请考虑使用接口:code
JDK中的抽象类的一个示例是AbstractMap,它是集合框架的一部分,它的子类(包括HashMap
、TreeMap
和ConcurrentHashMap
)共享AbstractMap
定义的许多方法(包括get
、put
、isEmpty
、containsKey
和containsValue
)。htm
JDK中实现多个接口的类的一个示例是HashMap,它实现了Serializable
、Cloneable
和Map<K, V>
接口。经过阅读这个接口列表,你能够推断出HashMap
的实例(不管是实现该类的开发人员或公司)能够克隆,可序列化(这意味着它能够转换为字节流)。请参阅Serializable Objects
部分,并具备map的功能,此外,Map<K, V>
接口已经加强了许多默认方法,例如merge
和forEach
,实现此接口的旧类没必要定义。对象
请注意,许多软件库都使用抽象类和接口,HashMap
类实现了几个接口,而且还扩展了抽象类AbstractMap
。
在面向对象的绘图应用程序中,你能够绘制圆形、矩形、线条、贝塞尔曲线和许多其余图形对象,这些对象都具备某些状态(例如:位置、方向、线条颜色、填充颜色)和行为(例如:moveTo
、rotate
、resize
、draw
)。全部图形对象中的一些状态和行为都是相同的(例如:位置、填充颜色和moveTo
),其余须要不一样的实现(例如,resize
或draw
)。全部GraphicObjects
必须可以本身绘制或调整大小,它们只是作的方式不一样,这是抽象超类的完美状况。你能够利用类似性并声明全部图形对象从同一个抽象父对象(例如,GraphicObject
)继承,以下图所示。
首先,声明一个抽象类GraphicObject
,以提供全部子类彻底共享的成员变量和方法,例如当前位置和moveTo
方法,GraphicObject
还声明了方法的抽象方法,例如draw
或resize
,它们须要由全部子类实现,但必须以不一样的方式实现,GraphicObject
类看起来像这样:
abstract class GraphicObject { int x, y; ... void moveTo(int newX, int newY) { ... } abstract void draw(); abstract void resize(); }
GraphicObject
的每一个非抽象子类(例如Circle
和Rectangle
)必须提供draw
和resize
方法的实现:
class Circle extends GraphicObject { void draw() { ... } void resize() { ... } } class Rectangle extends GraphicObject { void draw() { ... } void resize() { ... } }
在接口一节中,注意到实现接口的类必须实现全部接口的方法,可是,能够定义一个不实现全部接口方法的类,前提是该类被声明为abstract
,例如:
abstract class X implements Y { // implements all but one method of Y } class XX extends X { // implements the remaining method in Y }
在这种状况下,类X
必须是abstract
,由于它没有彻底实现Y
,但实际上,类XX
实现了Y
。
抽象类能够具备静态字段和静态方法,你能够像使用任何其余类同样使用带有类引用的静态成员(例如,AbstractClass.staticMethod()
)。