読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

派生クラスでtype aliasの指定を強制する

Scala

abstractなclass or trait に、型指定のない名前だけのtype aliasを書くと、派生クラスでこのtype aliasの定義を強制することができます。

abstract class Foo( ) {

  // 派生クラスで明示する必要があるtype alias
  // このクラスの派生クラスでは、Xのtype aliasを明示しなければならない。
  type X 
  
  // X型はこのクラス内で使用可能。
  var x:X
  def getX:X = x
  def setX(value:X):Unit = this.x=value
}

// Fooの派生クラスを作成。
var foo = new Foo() {
  // 派生クラスでX型を指定
  // 指定しないとコンパイルエラーになる。
  type X = String
  var x = "aaaa"
}
// メソッド呼び出し。XはStringなのでStringのメソッドが呼び出せる。
println( foo.getX.size )

実行結果です。

4

型の範囲を指定する

「<:」と「>:」でtype aliasで指定可能な型の範囲を指定できます。

  • 「type <名前> <: <型>」でtype aliasを「型派生の何か」に制限できます。
  • 同様に、「type <名前> >: <型>」でtype aliasは「型より上位の何か」になります。
  • 「type <名前> >: <型> <: <型>」として両方指定することもできます。
abstract class Hoge( ) {

  // 型の範囲指定付きtype declaration
  type Y <: Iterable[String] // 型「Y」は「Iterable[String]派生の何か」でなければならない
  type Z >: Iterable[String] <: Iterable[String] // 型「Z」は「Iterable[String]より上位の何か」でなければならない
  
  // 型「Y」は「Iterable[String]派生の何か」なので、
  // Iterable[String]として扱える。
  var y:Y
  def each( p:(String)=>Unit ):Unit = y.foreach( p )
  
  // 型「Z」は「少なくともIterable[String]」なので、
  // Iterable[String]派生のオブジェクトを代入したりできる。
  var z:Z = List("a", "b", "c")
}

// Hogeの派生クラスを作成。
var hoge = new Hoge() {
  // 派生クラスでY,Z型を指定
  type Y = Array[String]
  type Z = Iterable[String]
  
  // 互換性のない型を指定するととコンパイルエラーになる。
  // 以下はコンパイルエラー
  //type Y = Int
  //type Y = AnyRef
  //type Z = String
  //type Z = List[String]
  
  var y = Array( "a", "b", "c" )
}

// メソッド呼び出し。
hoge.each( i=>println(i) )

実行結果です。

a
b
c

なお、範囲指定を省略した場合、Nothing以上Any以下になります。つまり、最初のサンプルの

type X

type X  >: Nothing <: Any

と等価です。