抽象クラス

編集

抽象クラス(abstract class)は、抽象メソッド(abstraction method)を1つ以上持つクラスを指します。 抽象メソッドは具体的な処理内容を記述せず、メソッド名と引数と戻値の型の定義(シグネチャー)だけを宣言するメソッドです。

抽象クラスの宣言
abstract class クラス名 {
  //
}
抽象メソッドの宣言
  abstract 戻値の型 メソッド名(引数の型 引数名);

抽象クラスは、それ自体はインスタンス化することは出来ません。 インスタンス化することは出来ませんが、抽象クラスを別のクラスが継承する事は出来ます。 また、抽象クラスを super() を使うことでメソッドを呼び出せるので、抽象メソッドではないメソッド(具象メソッド)を持つことも、データメンバーも持つことも出来ます。 次の例では、Shapeのコンストラクターが抽象クラスの具象メソッドとなっています。

次のプログラムは、二次元座標系の図形について扱っています。

コード例
abstract class Shape {
    double x, y;
    Shape(double x, double y) {
        this.x = x;
        this.y = y;
    }
    abstract public String toString();
    abstract public double area();
}

class Square extends Shape {
    double wh;
    Square(double x, double y, double wh) {
        super(x, y);
        this.wh = wh;
    }
    public String toString() {
        return String.format("Square(%f, %f, %f)", this.x, this.y, this.wh);
    }
    public double area() {
        return this.wh * this.wh;
    }
}

class Recrangle extends Shape {
    double w, h;
    Recrangle(double x, double y, double w, double h) {
        super(x, y);
        this.w = w;
        this.h = h;
    }
    public String toString() {
        return String.format("Rectanle(%f, %f, %f, %f)", this.x, this.y, this.w, this.h);
    }
    public double area() {
        return this.w * this.h;
    }
}

class Circle extends Shape {
    double r;
    Circle(double x, double y, double r) {
        super(x, y);
        this.r = r;
    }
    public String toString() {
        return String.format("Square(%f, %f, %f)", this.x, this.y, this.r);
    }
    public double area() {
        return 3.1425926536 * this.r * this.r;
    }
}

class Main {
    public static void main(String[] args) {
        Shape[] shapes = {
            new Square(5.0, 10.0, 15.0),
            new Recrangle(13.0, 23.0, 20.0, 10.0),
            new Circle(3.0, 2.0, 20.0),
        };

        for (Shape shape: shapes) {
            System.out.println(String.format("%s: %f", shape, shape.area()));
        }
    }
}
実行結果
Square(5.000000, 10.000000, 15.000000): 225.000000
Rectanle(13.000000, 23.000000, 20.000000, 10.000000): 200.000000
Square(3.000000, 2.000000, 20.000000): 1257.037061
abstract class Shape
抽象クラス図形;他のクラスはこのクラスを継承。
Shape(double x, double y)
コンストラクター;private ですが、継承したクラスのコンストラクターから super として参照されるだけなので構いません。
double x, y
座標値
abstract public String toString()
文字列化(抽象メソッド)
abstract public double area()
面積(抽象メソッド)
class Square
具象クラス正方形;Shapeを継承
Square(double x, double y, double wh)
コンストラクター;追加の引数は一辺の長さ。
public String toString()
文字列化(具象メソッド)
public double area()
面積(具象メソッド)
class Rectangle
具象クラス長方形;Shapeを継承
Rectangle(double x, double y, double w, double h)
コンストラクター;追加の引数は幅と高さ。
public String toString()
文字列化(具象メソッド)
public double area()
面積(具象メソッド)
class Circle
具象クラス円;Shapeを継承
Circle(double x, double y, double r)
コンストラクター;追加の引数は半径。
public String toString()
文字列化(具象メソッド)
public double area()
面積(具象メソッド)
Shape[] shapes
図形の配列;Shapeを継承したクラスのインスタンスは3つとも要素になれますが、当のShapeはインスタンス化出来ないので要素になれません。
for (Shape shape: shapes) ...
Shapeを継承したクラスのインスタンスが来ることは判っているので、これでイテレーション出来ます。
呼んでいるメソッドも、抽象メソッドなので具体的なクラスは(Shapeを継承しているので)問いません。