Compound Types
<継承元の型> { <追加の定義...> }
で、継承元の型に合致し、さらに追加の定義を持つ型を作成?できます。
例えば
// Cat派生でかつmeowメソッドを持つ何かを引数として受け付ける関数
def meow( foo: Cat { def meow:Unit } ) = {
foo.meow
}
みたいなCompound Typesを受け取るメソッドを書くと、こいつの引数としては、
- Catクラスまたはその派生クラスで、
- かつ、meowメソッドを持つもの
のみ指定できます。つまり、以下のクラスのうちでは、Kittenのみが指定できます。
class Cat( name:String ) { def run = println(name + ": run!" ) } // Catの派生クラスでmeowメソッドを持つ class Kitten( name:String ) extends Cat(name) { def meow = println(name + ": meow!" ) } class Tiger( name:String ) { def run = println(name + ": run!" ) } class Bird( name:String ) { def fly = println(name + ": fly!" ) } ... meow( new Kitten( "mii" ) ) // meow( new Cat( "mike" ) ) // これはコンパイルエラー // meow( new Tiger( "tora" ) ) // これはコンパイルエラー // meow( new Bird( "piyo" ) ) // これはコンパイルエラー
なお、継承元の型は省略可能で、省略するとAnyRefになります。例えば、次のようなメソッドがあるとすると、
// runメソッドを持つ何かを引数として受け付ける関数
def run( foo: { def run:Unit } ) = {
foo.run
}
runメソッドを持つ、KittenやTigerが引数として指定できます。
run( new Kitten( "mii" ) ) run( new Tiger( "tora" ) ) //run( new Bird( "piyo" ) ) // これはコンパイルエラー