Deletions are marked like this. | Additions are marked like this. |
Line 32: | Line 32: |
上のコードのままだと、Animal以外のZooの作成が可能になってしまうし、そもそもZooクラスの中でAnimalのメソッドを呼び出せない。なぜなら、Tという型に制限がないので、IntegerやDoubleという型パラメータを指定してZooを作成できてしまうからである。 | 上のコードのままだと、Animal以外のZooの作成が可能になってしまう。 |
Line 34: | Line 34: |
Zoo<Integer>zooInt = new Zoo<Integer>(); // 可能だが??? | Zoo<Integer>zooInt = new Zoo<Integer>(); // 可能だが意味不明 |
Line 36: | Line 36: |
そこで、TというクラスをAnimalあるいはそのサブクラスに制限する。これを上限境界という。 |
また、そもそもこのままではZooクラスの中でAnimalのメソッドを呼び出せない。Tはどんな型でも可能だからである。 Zooの中でAnimalのメソッドを(キャスト無しに)呼び出すためには、TがAnimalクラスあるいはそのサブクラスであることを明示する必要がある。 |
Line 38: | Line 39: |
Javaでの上限境界指定は以下のようなものだった | そこで上限境界指定を行う。Javaでは以下のようなものだった |
Scalaの型システム
単純な型パラメータ
Javaでは以下のように書ける。
class Animal { } class Fish extends Animal { } class Zoo<T> { public void add(T animal) { } } ... Zoo<Animal>zoo = new Zoo<Animal>(); zoo.add(new Fish()); ...
これと等価な(たぶん)Scalaコードは以下。
class Animal class Fish extends Animal; class Zoo[T] { def add(a:T) { } } val zoo = new Zoo[Animal]; zoo add new Fish
上限境界と下限境界
上のコードのままだと、Animal以外のZooの作成が可能になってしまう。
Zoo<Integer>zooInt = new Zoo<Integer>(); // 可能だが意味不明
また、そもそもこのままではZooクラスの中でAnimalのメソッドを呼び出せない。Tはどんな型でも可能だからである。 Zooの中でAnimalのメソッドを(キャスト無しに)呼び出すためには、TがAnimalクラスあるいはそのサブクラスであることを明示する必要がある。
そこで上限境界指定を行う。Javaでは以下のようなものだった
class Zoo<T extends Animal> { ... } Zoo<Fish>fishZoo = new Zoo<Fish>(); // OK Zoo<Integer>intZoo = new Zoo<Integer>(); // エラー
Scalaでは以下になる
class Zoo[T <: Animal] { ... } .... val fishZoo = new Zoo[Fish]; // OK val intZoo = new Zoo[Int]; // エラー