5.2.8、抽象方法和抽象类

这篇Java教程基于JDK1.8。教程中的示例和实践不会使用未来发行版中的优化建议。
5.2.8、抽象方法和抽象类

抽象类是指 通过 abstract 描述的类 — 它可以有或者没有抽象方法。抽象类不能实例化,但可以子类化。

抽象方法是指只有声明没有实现的方法(指没有括号,分号结尾):

abstract void moveTo(double deltaX, double deltaY);

如果类包含抽象方法,该类必须用 abstract 予以修饰:

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

当扩展抽象类时,子类通常要实现抽象类的所有抽象方法,如若不然,该子类也要声明为abstract的。

抽象类和接口比较

抽象类和接口很像,不能实例化,可以同时有方法声明和方法实现。但在抽象类中,可以声明非静态和非 final 的字段,也可以定义 publicprotectedprivate 概念的方法。在接口中,所有的字段都是public staticfinal 的,所有声明和定义的方法都是 public 的。而且,你只能扩展一个类(不管它是否是抽象类),但可以实现任意数量的接口。

那么你应该如何选择 抽象类 或 接口呢?

  • 以下场景使用抽象类

    • 要在相关联的类之间共享代码
    • 扩展抽象类有许多公共的方法和字段,或者需要修改访问控制符
    • 要声明 non-staticnon-final 的字段。这使你定义能够访问和修改它们所属对象的状态的方法
  • 以下场景使用接口

    • 不相关的类要实现接口
    • 指定一种特殊数据类型的行为,但不确定谁来实现它的行为
    • 发挥类型多继承的优势

抽象类的一个例子是 JDK 的 * AbstractMap* ,集合框架的一部分。它的子类共享了 * AbstractMap* 定义的许多方法。

JDK 中实现多个接口的一个例子是 HashMap 。依次实现了接口 SerializableCloneableMap<K, V>,通过阅读接口列表,可以推断 HashMap 的实例可以克隆、序列化,并且拥有 map 的能力。 Map<K, V> 接口通过许多默认方法(mergeforEach)予以增强,实现该接口的那些旧类不需要重新定义这些方法。

注意许多软件包会同时使用抽象类和接口,比如 HashMap 类实现了许多方法同时也扩展了 AbstractMap 类。

抽象类示例

在面向对象绘图应用中,可以绘制圆形、方形、线、曲线以及其他图形对象。这些对象都会有状态(位置、取向、颜色、填充色)和 行为(比如:moveTo, rotate, resize, draw等等)。其中有些状态和行为对所有图形都是一样的(比如:position, fill color, and moveTo)。另外一些则需要不同的实现(比如:resize or draw)。所有的 GraphicObjects 都必须能 drawresize ,不同的如何实现。这是抽象类的一个完美场景。可以发挥图形相似性的优势,让他们继承同一个抽象父类(比如:GraphicObject)如下图所示:
在这里插入图片描述
首先,声明抽象类 GraphicObject ,提供所有子类可以共享的成员变量和方法,比如positionmoveTo方法。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 的方法。

类成员

抽象类可以有 static 的变量和方法。可以使用类引用来访问静态成员(比如:AbstractClass.staticMethod()),就如同在其他类中所使用的那样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值