抽象方法和类
抽象类是声明为abstract
的类——它可以或不用包含抽象方法。抽象类不能被实例化,但他们可以被继承。
抽象类是一个声明但没有实现的方法(没有大括号,尾随分号),例如:
abstract void moveTo(double deltaX, double deltaY);
如果一个类包含抽象方法,这个类必须声明为abstract
,如下:
public abstract class GraphicObject { // declare fields // declare non-abstract methods abstract void draw(); }
当抽象类被继承,子类通常要为父类的所有抽象方法提供实现。但是,如果没有全部实现,子类也要声明为abstract
。
注意:接口的所有方法隐式是abstract,所以abstract修饰符不用使用于接口方法(可以使用,非必须)。
抽象类和接口
不同于接口,抽象类可以包含不是static和final的字段,而且他们可以包含被实现的方法。这种抽象类类似接口,不同之处在于它们提供了部分实现,把它留给子类来完成其他实现。如果一个抽象类仅包含抽象方法的声明,它应该被声明为接口。
类层次中,类可以实现多个接口,无论两两之间是否有联系。例如考虑下Comparable和
Cloneable。
通过比较,共享实现,最经常用的就是继承抽象类。一个抽象类,是被一个和它有很多相似的(抽象类的部分实现),但是有些不同(抽象方法)的子类继承。
抽象类例子
面向对象的绘图应用程序中,可以画圆形,矩形,线条,Bezier曲线,和其他很多图形对象。这些对象公用上都包含一定的状态(例如:位置,方向,线条颜色,填充颜色)和行为(例如:移动,旋转,缩放,画)。所有图形对象一些状态和行为都是相同的,例如:位置,填充颜色,和移动。其他需要不同的实现,例如,缩放或绘制。所有图形对象必须知道如何绘制或缩放自己,他们是不同的,他们是如何做到这一点。这是一个完美的抽象父类。您可以利用相似性,声明的所有图形对象继承自同一个抽象的父对象,例如,GraphicObjec。
首先,你声明抽象类GraphicObject
提供成员变量和方法,这完全由所有子类共享,这像当前位置,移动方法。GraphicObject也要声明抽象方法,如绘制或缩放,这需要给子类实现,但使用不同的方式实现。
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。
类成员
抽象类可以有static字段和static方法。可以通过类引用访问static成员——例如,AbstractClass.staticMethod()——就像用其他类一样。