Scala の with キーワード
この記事では、Scala で with
キーワードを使用する方法を示します。
Scala で with
キーワードを使用する
このキーワードは、通常、ミックスインでクラス構成を処理するときに使用されます。 ミックスインは、クラスを構成するために使用される特性です。
これは、インターフェースを実装できる Java クラスにいくぶん似ています。
with
キーワードをよりよく理解するための例を見てみましょう。
abstract class vehicle {
val message: String
}
class Car extends vehicle {
val message = "I'm an instance of class vehicle"
}
trait sportsCar extends vehicle {
def ourMessage = message.toUpperCase()
}
class temp extends Car with sportsCar
val obj = new temp
println(obj.message) // I'm an instance of class vehicle
println(obj.ourMessage) // I'M AN INSTANCE OF CLASS VEHICLE
上記のコードでは、クラス temp
にスーパークラス Car
と mixin sportsCar
があります。 クラスは 1つのスーパークラスのみを拡張できますが、with
キーワードを使用して多数の mixin を拡張できます。 スーパークラスとミックスインは同じ supertype
を持つことができます。
別の例を見てみましょう。 まず、型 T
といくつかの標準的な反復子メソッドを持つ抽象クラスを作成しましょう。
abstract class ourIterator {
type T
def hasNext: Boolean
def next(): T
}
さて、hasNext
と next
である T
のすべての抽象メンバーの実装が存在する具象クラスを作成しましょう。
class StringIterator(str: String) extends ourIterator {
type T = Char
private var i = 0
def hasNext = i < str.length
def next() =
{
val ch = str.charAt(i)
i += 1
ch
}
}
クラス ourIterator
も拡張するトレイトを作成しましょう。
trait anotherIterator extends ourIterator {
def foreach(X: T => Unit): Unit = while (hasNext) X(next())
}
トレイト anotherIterator
は、次の要素 while(hasNext)
がある限り、関数 X: T => Unit
を次の要素 next()
で継続的に呼び出す foreach()
メソッドを実装します。
anotherIterator
はトレイトであるため、ourIterator
クラスの抽象メンバーを実装する必要はありません。 次に示すように、anotherIterator
と StringIterator
の機能を単一のクラスに結合できます。
class temp extends StringIterator("Tony") with anotherIterator
val obj = new temp
obj.foreach(println)
完全な作業コード:
abstract class ourIterator {
type T
def hasNext: Boolean
def next(): T
}
class StringIterator(str: String) extends ourIterator {
type T = Char
private var i = 0
def hasNext = i < str.length
def next() =
{
val ch = str.charAt(i)
i += 1
ch
}
}
trait anotherIterator extends ourIterator {
def foreach(X: T => Unit): Unit = while (hasNext) X(next())
}
class temp extends StringIterator("Tony") with anotherIterator
val obj = new temp
obj.foreach(println)
出力:
T
o
n
y
上記のコードでは、新しいクラス temp
は StringIterator
を superclass
として、anotherIterator
を mixin として持ちます。 単一継承だけでは、このレベルの柔軟性を実現することはできません。