Previous | Next | Trail Map | Writing Java Programs | オブジェクト、クラス、インタフェース


Abstract クラスとメソッドの書き方

abstract クラス

時々、定義するクラスが抽象的な概念を表し、インスタンス化されるべきではない時がある。 例えば現実の世界の食物を取る。 今までに食物のインスタンスを見たことがあるか? ないだろう。その代わりに見るものは人参、リンゴ、(私のお気に入りの)チョコレートのインスタンスである。 食物が食べることのできるものという抽象的な概念を表す。 それは存在する食物のインスタンスでは意味をなさない。

同様にオブジェクト指向のプログラミングで、抽象的な概念を設計したいが、そのインスタンスを作成したくないこともある。 例えば、 java.lang パッケージの Number クラスは数の抽象的な概念を表す。 それはプログラムで数を設計することは意味をなすが、一般的な番号オブジェクトを作成することでは意味をなさない。 その代わりに、 Number クラスは、特定のある種類の数を実装するIntegerとFloatのようなクラスに対するスーパークラスとしてだけ意味をなす。 抽象的な概念を実装し、インスタンス化されるべきでない Number のようなクラスは abstract クラスと呼ばれる。 abstract クラスはサブクラス化されることができるだけで、インスタンス化されないクラスである。

クラスが abstract クラスであると宣言するためには、クラス宣言の class キーワードの前に abstract キーワードを使用する。

abstract class Number {
    . . .
}

abstract クラスをインスタンス化しようと試みるなら、コンパイラは次のに類似したエラーを表示して、プログラムをコンパイルすることを拒否する。

AbstractTest.java:6: class AbstractTest is an abstract class.
 It can't be instantiated.
        new AbstractTest();
        ^
1 error

Abstract メソッド

abstract クラスが抽象メソッド、すなわち、実装がないメソッドを含むことがある。 このようにして、 abstract クラスは完全なプログラム作成インタフェースを定義することができ、これによって、そのプログラム作成インタフェースを実装するために必要なすべてのメソッドのメソッド宣言をそのサブクラスに提供している。 しかし、 abstract クラスはそのサブクラスまでメソッドの実装詳細の一部またはすべてを伝えることができる。

abstract メソッドで abstract クラスを作成する例を見よう。 オブジェクト指向の描画アプリケーションで、円、矩形、行、 Beziers などを描くことができる。 これらのグラフィックオブジェクトのそれぞれが、ある特定の状態(位置、バウンディングボックス)と振る舞い(移動、サイズ変更、描画)を共有する。 これらの相似性を利用して、それらのすべてが同じ親オブジェクト − GraphicObject − から継承するように宣言することができる。

「 PENDING: picture 」

しかし、グラフィックオブジェクトはいろいろな意味で本質的に異なる。円を描くことは矩形を描くこととは非常に異なる。 グラフィックスオブジェクトはこれらのタイプの状態あるいは振る舞いを共有することができない。 また一方では、すべての GraphicObject がそれ自身を描く方法を知っていなくてはならない。それらは描かれる方法が異なる。 これは抽象的なスーパークラスの完ぺきな状況である。

現在の位置や moveTo() メソッドのようなすべてのサブクラスを完全に共用するメンバ変数とメソッドを提供するために、最初に abstract クラスである GraphicObject を宣言する。 GraphicObject はすべてのサブクラスにより実装されているが、完全に異なる方法(スーパークラスでの適当なデフォルトの実装が意味をなさない)で実装される必要があった draw() のようなメソッドにも抽象メソッドを宣言する。 GraphicObject クラスは次のようになる。

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

Circle と Rectangle のような GraphicObject の抽象的でない各サブクラスが、 draw() メソッドの実装を提供しなければならない。

class Circle extends GraphicObject {
    void draw() {
        . . .
    }
}
class Rectangle extends GraphicObject {
    void draw() {
        . . .
    }
}

abstract クラスはその中に抽象メソッドを持つように要求されない。 しかし、abstract クラスあるいはスーパークラスの中に抽象メソッドを持つクラスは abstract クラスとして宣言されなければならない。


Previous | Next | Trail Map | Writing Java Programs | オブジェクト、クラス、インタフェース