Java™ 教程(抽象方法和类)

抽象方法和类

抽象类是一个声明为abstract的类 — 它可能包括也可能不包括抽象方法,抽象类没法实例化,但能够进行子类化。html

抽象方法是在没有实现的状况下声明的方法(没有大括号,后跟分号),以下所示:java

abstract void moveTo(double deltaX, double deltaY);

若是一个类包含抽象方法,那么该类自己必须被声明为abstract,如:segmentfault

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}

当抽象类被子类化时,子类一般为其父类中的全部抽象方法提供实现,可是,若是没有,那么子类也必须声明为abstractapi

注意:未声明为 defaultstatic的接口(参见 接口部分)中的方法是隐式抽象的,所以 abstract修饰符不用于接口方法(能够使用,但不须要)。

抽象类与接口相比

抽象类与接口相似,你不能实例化它们,它们可能包含有或没有实现声明的方法的组合,可是,使用抽象类,你能够声明非静态和final的字段,并定义publicprotectedprivate的具体方法。使用接口,全部字段都自动为publicstaticfinal,而且你声明或定义的全部方法(做为默认方法)都是public,此外,你只能扩展一个类,不管它是不是抽象的,而你能够实现任意数量的接口。oracle

你应该使用哪一个,抽象类或接口?框架

  • 若是任何这些语句适用于你的状况,请考虑使用抽象类:spa

    • 你但愿在几个密切相关的类之间共享代码。
    • 你但愿扩展抽象类的类具备许多公共方法或字段,或者须要非公共的访问修饰符(如protectedprivate)。
    • 你想声明非静态或非最终字段,这使你可以定义可以访问和修改它们所属的对象的状态的方法。
  • 若是任何这些语句适用于你的状况,请考虑使用接口:code

    • 你但愿不相关的类将实现你的接口,例如,ComparableCloneable接口由许多不相关的类实现。
    • 你但愿指定特定数据类型的行为,但不关心谁实现其行为。
    • 你但愿利用类型的多重继承。

JDK中的抽象类的一个示例是AbstractMap,它是集合框架的一部分,它的子类(包括HashMapTreeMapConcurrentHashMap)共享AbstractMap定义的许多方法(包括getputisEmptycontainsKeycontainsValue)。htm

JDK中实现多个接口的类的一个示例是HashMap,它实现了SerializableCloneableMap<K, V>接口。经过阅读这个接口列表,你能够推断出HashMap的实例(不管是实现该类的开发人员或公司)能够克隆,可序列化(这意味着它能够转换为字节流)。请参阅Serializable Objects部分,并具备map的功能,此外,Map<K, V>接口已经加强了许多默认方法,例如mergeforEach,实现此接口的旧类没必要定义。对象

请注意,许多软件库都使用抽象类和接口,HashMap类实现了几个接口,而且还扩展了抽象类AbstractMap

抽象类示例

在面向对象的绘图应用程序中,你能够绘制圆形、矩形、线条、贝塞尔曲线和许多其余图形对象,这些对象都具备某些状态(例如:位置、方向、线条颜色、填充颜色)和行为(例如:moveTorotateresizedraw)。全部图形对象中的一些状态和行为都是相同的(例如:位置、填充颜色和moveTo),其余须要不一样的实现(例如,resizedraw)。全部GraphicObjects必须可以本身绘制或调整大小,它们只是作的方式不一样,这是抽象超类的完美状况。你能够利用类似性并声明全部图形对象从同一个抽象父对象(例如,GraphicObject)继承,以下图所示。

classes-graphicObject.gif

首先,声明一个抽象类GraphicObject,以提供全部子类彻底共享的成员变量和方法,例如当前位置和moveTo方法,GraphicObject还声明了方法的抽象方法,例如drawresize,它们须要由全部子类实现,但必须以不一样的方式实现,GraphicObject类看起来像这样:

abstract class GraphicObject {
    int x, y;
    ...
    void moveTo(int newX, int newY) {
        ...
    }
    abstract void draw();
    abstract void resize();
}

GraphicObject的每一个非抽象子类(例如CircleRectangle)必须提供drawresize方法的实现:

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())。


上一篇:Object做为超类

下一篇:数字

相关文章
相关标签/搜索