2010-11-26 7 views
5

相続を表すために異なる表記法がありますか?ジェネリックでは、<:-operatorを使用する必要があります。通常のクラス継承では、extendsキーワードを使用する必要があります。相続を表現するための異なる表記

私はこの記述する必要があります例えば

class X[A <: B] extends Y 

をしかし、このような何か書いていない理由:

class X[A <: B] <: Y 

または

class X[A extends B] extends Y // like Java 

を、私は現在の表記には問題がありませんしかし、私は、ジェネリックの型階層を別のやり方で知らせる理由があるかどうかを知りたい。

答えて

12

まあ、そうすることから Scalaのを止める何もはありませんが、実際の問題として、彼らはすべてので同じことを発現しません。そして、実際には、Javaでは、X super Yと書くことができますが、class X super Yと言うことはできません。

キーワードextendsは、クラスの継承の関係を表します。一方、<:>:は、タイプの境界の1つの関係を表します。私がX <: Yと言うとき、XYの両方がStringであることが有効です。一方、String extends Stringは無意味です。また、List[String] <: List[AnyRef]でも、List[String] extends List[AnyRef]は無意味です。そして、ちょうどその点を作るために、それはではないそれはSet[String] <: Set[AnyRef]の真です。これらすべての例で私はちょうど我々が同じクラスについて話しているが、必ずしも同じものではない。タイプ

もちろん、ビュー境界(<%)やコンテキスト境界(:)など、タイプ間には他の関係もあります。

ので、extends<:を暗示という理由だけで、一人では、同じキーワードを使用して回避するための十分な理由で、<:extendsを意味していること従っていません。それに加えてタイプ間の関係はであり、クローズドな取引がほとんどあります。

+1

++クラスと型の違いについては、 –

+0

を参照してください。クラスと型は異なる表記を使用するのが理にかなっています。説明ありがとう。 – sschaef

7

あなたの例をその単純な1つのケースを超えて拡張すると、より明白になります。

多重継承:

class C[A] extends X with Y with Z 

ミックスイン:

val x = new X with Y 

パラメータ化:

class X[A <: B] extends Y[A] 

複数の(関連の)タイプのparams:

class X[A >: B, B](x: A, xs: Seq[B]) 

コンテキスト境界:

class X[A : Manifest] 

表示範囲:

class X[A <% Ordered[A]] 

ジェネリック方法

class Foo[B] { 
    def bar[A <: B](x: A) = ... 
} 

あなたが見ることができるように、typeパラメータで指定される関係クラスを宣言するときに利用できる単純な線形階層よりもはるかに豊富です限界のために低い。

それは、クラスやメソッドのジェネリック型パラメータは非常に多くの場合、あなたが書くことができるように、推論されることは注目にも価値がある:

val myList = List(1, 2, 3) 

代わりの

val myList = List[Int](1, 2, 3) 

そうで表記方法非常に異なっています。

更新

1つの特定の例は、ちょうど同時に両方の表記を使用することを実証し、彼らは明確なままにする必要があるかを示す、心に春ました:

def someMethod[T <: Foo with Bar](x: T) = ... 

これは、その型のparamが必要ですTは、FooBarの両方で混在するサブタイプです。

同じ構造タイプで適用されます。

type Closable = { def close: Unit } //alias for a structural type 
def someMethod[T <: Closable](x: T) = ... 
関連する問題