Scala ひと巡り : サブクラス化 (Subclassing)

原ページ

Scala のクラスは拡張可能です。サブクラスの機構により、与えられたスーパークラスの全メンバーの継承と、クラスメンバの追加定義によって、クラスを特化できます。

次は 1 つの例です:

class Point(xc: Int, yc: Int) { val x: Int = xc val y: Int = yc def move(dx: Int, dy: Int): Point = new Point(x + dx, y + dy) } class ColorPoint(u: Int, v: Int, c: String) extends Point(u, v) { val color: String = c def compareWith(pt: ColorPoint): Boolean = (pt.x == x) && (pt.y == y) && (pt.color == color) override def move(dx: Int, dy: Int): ColorPoint = new ColorPoint(x + dy, y + dy, color) }

この例では最初に、場所を表す新しいクラス Point を定義します。次に、クラス Point を拡張するクラス ColorPoint を定義します。

これは次のような結果になります:

    • クラス ColorPoint は、そのスーパークラス Point からすべてのメンバーを継承します。;この場合、メソッド move と同様、値 x、y も継承します。

    • サブクラス ColorPoint は、(継承した)メソッドの集合に新しいメソッド compareWith を加えます。

    • Scala ではメンバー定義をオーバライドできます; この場合、クラス Point から継承した move メソッドをオーバライドします。これにより、ColorPoint オブジェクトのクライアントは、クラス Point の move メソッドにアクセスできなくなります。クラス ColorPoint 内では、継承されたメソッド move は スーパー呼び出し: super.move(...) を使ってアクセスできます。メソッドオーバーライドが非変の(つまり、オーバーライドするメソッドが同じシグニチャを持たなければならない) Java と異なり、Scala では反変/共変方式でメソッドをオーバライドできます。上の例では、このフィーチャーを利用してメソッド move に、スーパークラス Point で指定された Point オブジェクトを返す代わりに ColorPoint オブジェクトを返させています。

    • サブクラスはサブ型を定義します; このことは今の場合、Point オブジェクトが必要とされるときはいつでも、ColorPoint オブジェクトを使えることを意味します。

複数の他クラスを継承したい場合、純粋なサブクラス化ではなく、ミックスインベースのクラス合成 [5] を利用する必要があります。