Tutorial_7

「Tutorial_7」の編集履歴(バックアップ)一覧はこちら

Tutorial_7 - (2010/08/17 (火) 11:37:52) の最新版との変更点

追加された行は緑色になります。

削除された行は赤色になります。

[[トップ>トップページ]] > [[チュートリアル和訳>Tutorial和訳]] > [[7 Traits>Tutorial_7]] #co(){*7 Traits Apart from inheriting code from a super-class, a Scala class can also import code from one or several traits.} *7 トレイト スーパークラスからコードを継承する以外にも、Scalaでは1つあるいは複数のトレイトからコードをインポートできます。 #co(){Maybe the easiest way for a Java programmer to understand what traits are is to view them as interfaces which can also contain code. In Scala, when a class inherits from a trait, it implements that traits’s interface, and inherits all the code contained in the trait.} Javaプログラマがトレイトとは何かを理解する一番簡単な方法は、コードを含むことも可能なインターフェイスとみなすことでしょう。Scalaでは、あるクラスがトレイトから継承した場合、そのトレイトのインターフェイスを実装し、そのトレイトに含まれるコードも全て継承します。 #co(){To see the usefulness of traits, let’s look at a classical example: ordered objects. It is often useful to be able to compare objects of a given class among themselves, for example to sort them. In Java, objects which are comparable implement the Comparable interface. In Scala, we can do a bit better than in Java by defining our equivalent of Comparable as a trait, which we will call Ord.} トレイトの有用性を見る為に、古典的な例である、順序付きオブジェクトを見てみましょう。あるクラスのオブジェクト同士を比較できると、例えばソートしたりする場合など、しばしば役に立ちます。Javaでは、比較可能なオブジェクトは Comparable インターフェイスを実装します。Scalaでは、Comparable と同等品の、Ordと呼ぶことにするトレイトを定義することで、Javaよりもう少しうまくやれます。 #co(){When comparing objects, six different predicates can be useful: smaller, smaller or equal, equal, not equal, greater or equal, and greater. However, defining all of them is fastidious, especially since four out of these six can be expressed using the remaining two. That is, given the equal and smaller predicates (for example), one can express the other ones. In Scala, all these observations can be nicely captured by the following trait declaration:} オブジェクトを比較するには、6つの異なる述語、小さい・小さいか等しい・等しい・等しくない・大きいか等しい・大きい、があると便利です。しかしそれら全てを定義するのは冗長に過ぎます。なぜなら6つのうちの2つを使って残りの4つは表せるのですから。例えば、等しいと小さいの2つの述語があれば、他を表すことができます。Scalaでは、それらは次のようなトレイト宣言でうまく表せます。 trait Ord { def < (that: Any): Boolean def <=(that: Any): Boolean = (this < that) || (this == that) def > (that: Any): Boolean = !(this <= that) def >=(that: Any): Boolean = !(this < that) } #co(){This definition both creates a new type called Ord, which plays the same role as Java’s Comparable interface, and default implementations of three predicates in terms of a fourth, abstract one. The predicates for equality and inequality do not appear here since they are by default present in all objects.} この定義によって、Java の Comparable インターフェイスと同じ役割をする Ord と呼ばれる型を作ると共に、抽象的な述語1つを使って3つの述語のデフォルト実装が行われます。等しい・等しくないという述語は、全てのオブジェクトにデフォルトで存在するため、ここには現れません。 #co(){The type Any which is used above is the type which is a super-type of all other types in Scala. It can be seen as a more general version of Java’s Object type, since it is also a super-type of basic types like int, float, etc.} 上の例で 使われている Any 型は Scala の全ての型のスーパータイプの型です。Javaの Object 型より更に一般的といえます。なぜなら、Int や Float といった基本型のスーパータイプでもあるからです。 #co(){To make objects of a class comparable, it is therefore sufficient to define the predicates which test equality and inferiority, and mix in the Ord class above. As an example, let’s define a Date class representing dates in the Gregorian calendar. Such dates are composed of a day, a month and a year, which we will all represent as integers. We therefore start the definition of the Date class as follows:} 従って、比較可能なクラスのオブジェクトを作る為には、等しいことと小さいことを判定する述語を定義し、上記 Ord トレイトをミックスインすれば充分です。例として、グレゴリオ暦の日付を表す Date クラスを定義してみましょう。そのような日付は、全て整数値である日・月・年から成ります。従って Date クラスの定義は次のようになります。 class Date(y: int, m: Int, d: Int) extends Ord { def year = y def month = m def day = d override def toString(): String = year + "" + month + "" + day #co(){The important part here is the extends Ord declaration which follows the class name and parameters. It declares that the Date class inherits from the Ord trait.} ここで重要なことは、クラス名とパラメータに続く extends Ord 宣言です。これは Date クラスが Ord トレイトを継承することを宣言しています。 #co(){Then, we redefine the equals method, inherited from Object, so that it correctly compares dates by comparing their individual fields. The default implementation of equals is not usable, because as in Java it compares objects physically. We arrive at the following definition:} そして、Object から継承している equals メソッドを再定義し、個々のフィールドを比較することで正しく日付を比較するようにします。equals の Java でのデフォルト実装は、オブジェクトを物理的に比較するため使えません。下記のような定義になります。 override def equals(that: Any): Boolean = that.isInstanceOf[Date] && { val o = that.asInstanceOf[Date] o.day == day && o.month == month && o.year == year } #co(){This method makes use of the predefined methods isInstanceOf and asInstanceOf. The first one, isInstanceOf, corresponds to Java’s instanceof operator, and returns true if and only if the object on which it is applied is an instance of the given type. The second one, asInstanceOf, corresponds to Java’s cast operator: If the object is an instance of the given type, it is viewed as such, otherwise a ClassCastException is thrown.} このメソッドでは予め定義された、isInstanceOf と asInstanceOf というメソッドを使用しています。最初の isInstanceOf は、Java の instanceof 演算子に対応しており、適用されたオブジェクトが与えられた型のインスタンスである場合にのみ真を返します。2つめの asInstanceOf は、Java のキャスト演算子に対応します。もしオブジェクトが与えられた型のインスタンスならばそのように観られるようになり、そうでなければ ClasscastException が投げられます。 #co(){Finally, the last method to define is the predicate which tests for inferiority, as follows. It makes use of another predefined method, error, which throws an exception with the given error message.} 最後に下記のように、小さいことを判定する述語を定義します。別の予め定義されたメソッドである error を使います。error は与えられたエラーメッセージ付きの例外を投げるメソッドです。 def <(that: Any): Boolean = { if (!that.isInstanceOf[Date]) error("cannot compare " + that + " and a Date") val o = that.asInstanceOf[Date] (year < o.year) || (year == o.year && (month < o.month || (month == o.month && day < o.day))) } #co(){This completes the definition of the Date class. Instances of this class can be seen either as dates or as comparable objects. Moreover, they all define the six comparison predicates mentioned above: equals and < because they appear directly in the definition of the Date class, and the others because they are inherited from the Ord trait.} これで Date クラスの定義が完了しました。このクラスのインスタンスは日付であり比較可能なオブジェクトでもあります。更に、上で述べた6つの比較用の述語が定義されています。equalsと < は Date クラスの定義の中に直接現れており、他は Ord トレイトから継承しています。 #co(){Traits are useful in other situations than the one shown here, of course, but discussing their applications in length is outside the scope of this document.} トレイトがここで示したよりも有用な状況があるのは勿論ですが、そういった例を長々と議論するのはこの文書の目的から外れます。 #center(){[[前ページ>>Tutorial_6]]  [[目次>>Tutorial和訳]]  [[次ページ>>Tutorial_8]]} ---- #comment()
[[トップ>トップページ]] > [[チュートリアル和訳>Tutorial和訳]] > [[7 Traits>Tutorial_7]] #co(){*7 Traits Apart from inheriting code from a super-class, a Scala class can also import code from one or several traits.} *7 トレイト スーパークラスからコードを継承する以外にも、Scalaでは1つあるいは複数の&italic(){トレイト}からコードをインポートできます。 #co(){Maybe the easiest way for a Java programmer to understand what traits are is to view them as interfaces which can also contain code. In Scala, when a class inherits from a trait, it implements that traits’s interface, and inherits all the code contained in the trait.} Javaプログラマがトレイトとは何かを理解する一番簡単な方法は、コードを含むことも可能なインターフェイスとみなすことでしょう。Scalaでは、あるクラスがトレイトから継承した場合、そのトレイトのインターフェイスを実装し、そのトレイトに含まれるコードも全て継承します。 #co(){To see the usefulness of traits, let’s look at a classical example: ordered objects. It is often useful to be able to compare objects of a given class among themselves, for example to sort them. In Java, objects which are comparable implement the Comparable interface. In Scala, we can do a bit better than in Java by defining our equivalent of Comparable as a trait, which we will call Ord.} トレイトの有用性を見るために、古典的な例である、順序付きオブジェクトを見てみましょう。あるクラスのオブジェクト同士を比較できると、例えばソートしたりする場合など、しばしば役に立ちます。Javaでは、比較可能なオブジェクトは Comparable インターフェイスを実装します。Scalaでは、Comparable と同等品の、Ordと呼ぶことにするトレイトを定義することで、Javaよりもう少しうまくやれます。 #co(){When comparing objects, six different predicates can be useful: smaller, smaller or equal, equal, not equal, greater or equal, and greater. However, defining all of them is fastidious, especially since four out of these six can be expressed using the remaining two. That is, given the equal and smaller predicates (for example), one can express the other ones. In Scala, all these observations can be nicely captured by the following trait declaration:} オブジェクトを比較するには、6つの異なる述語、小さい・小さいか等しい・等しい・等しくない・大きいか等しい・大きい、があると便利です。しかしそれら全てを定義するのは冗長に過ぎます。なぜなら6つのうちの2つを使って残りの4つは表せるのですから。例えば、等しいと小さいの2つの述語があれば、他を表すことができます。Scalaでは、それらは次のようなトレイト宣言でうまく表せます。 trait Ord { def < (that: Any): Boolean def <=(that: Any): Boolean = (this < that) || (this == that) def > (that: Any): Boolean = !(this <= that) def >=(that: Any): Boolean = !(this < that) } #co(){This definition both creates a new type called Ord, which plays the same role as Java’s Comparable interface, and default implementations of three predicates in terms of a fourth, abstract one. The predicates for equality and inequality do not appear here since they are by default present in all objects.} この定義によって、Java の Comparable インターフェイスと同じ役割をする Ord と呼ばれる型を作ると共に、抽象的な述語1つを使って3つの述語のデフォルト実装が行われます。等しい・等しくないという述語は、全てのオブジェクトにデフォルトで存在するため、ここには現れません。 #co(){The type Any which is used above is the type which is a super-type of all other types in Scala. It can be seen as a more general version of Java’s Object type, since it is also a super-type of basic types like int, float, etc.} 上の例で 使われている Any 型は Scala の全ての型のスーパータイプの型です。Javaの Object 型より更に一般的といえます。なぜなら、Int や Float といった基本型のスーパータイプでもあるからです。 #co(){To make objects of a class comparable, it is therefore sufficient to define the predicates which test equality and inferiority, and mix in the Ord class above. As an example, let’s define a Date class representing dates in the Gregorian calendar. Such dates are composed of a day, a month and a year, which we will all represent as integers. We therefore start the definition of the Date class as follows:} 従って、比較可能なクラスのオブジェクトを作るためには、等しいことと小さいことを判定する述語を定義し、上記 Ord トレイトをミックスインすれば充分です。例として、グレゴリオ暦の日付を表す Date クラスを定義してみましょう。そのような日付は、全て整数値である日・月・年から成ります。従って Date クラスの定義は次のようになります。 class Date(y: int, m: Int, d: Int) extends Ord { def year = y def month = m def day = d override def toString(): String = year + "" + month + "" + day #co(){The important part here is the extends Ord declaration which follows the class name and parameters. It declares that the Date class inherits from the Ord trait.} ここで重要なことは、クラス名とパラメータに続く &bold(){extends} Ord 宣言です。これは Date クラスが Ord トレイトを継承することを宣言しています。 #co(){Then, we redefine the equals method, inherited from Object, so that it correctly compares dates by comparing their individual fields. The default implementation of equals is not usable, because as in Java it compares objects physically. We arrive at the following definition:} そして、Object から継承している equals メソッドを再定義し、個々のフィールドを比較することで正しく日付を比較するようにします。equals の Java でのデフォルト実装は、オブジェクトを物理的に比較するため使えません。下記のような定義になります。 override def equals(that: Any): Boolean = that.isInstanceOf[Date] && { val o = that.asInstanceOf[Date] o.day == day && o.month == month && o.year == year } #co(){This method makes use of the predefined methods isInstanceOf and asInstanceOf. The first one, isInstanceOf, corresponds to Java’s instanceof operator, and returns true if and only if the object on which it is applied is an instance of the given type. The second one, asInstanceOf, corresponds to Java’s cast operator: If the object is an instance of the given type, it is viewed as such, otherwise a ClassCastException is thrown.} このメソッドではあらかじめ定義された、isInstanceOf と asInstanceOf というメソッドを使用しています。最初の isInstanceOf は、Java の instanceof 演算子に対応しており、適用されたオブジェクトが与えられた型のインスタンスである場合にのみ真を返します。2つめの asInstanceOf は、Java のキャスト演算子に対応します。もしオブジェクトが与えられた型のインスタンスならばそのように観られるようになり、そうでなければ ClasscastException が投げられます。 #co(){Finally, the last method to define is the predicate which tests for inferiority, as follows. It makes use of another predefined method, error, which throws an exception with the given error message.} 最後に下記のように、小さいことを判定する述語を定義します。別のあらかじめ定義されたメソッドである error を使います。error は与えられたエラーメッセージ付きの例外を投げるメソッドです。 def <(that: Any): Boolean = { if (!that.isInstanceOf[Date]) error("cannot compare " + that + " and a Date") val o = that.asInstanceOf[Date] (year < o.year) || (year == o.year && (month < o.month || (month == o.month && day < o.day))) } #co(){This completes the definition of the Date class. Instances of this class can be seen either as dates or as comparable objects. Moreover, they all define the six comparison predicates mentioned above: equals and < because they appear directly in the definition of the Date class, and the others because they are inherited from the Ord trait.} これで Date クラスの定義が完了しました。このクラスのインスタンスは日付であり比較可能なオブジェクトでもあります。更に、上で述べた6つの比較用の述語が定義されています。equalsと < は Date クラスの定義の中に直接現れており、他は Ord トレイトから継承しています。 #co(){Traits are useful in other situations than the one shown here, of course, but discussing their applications in length is outside the scope of this document.} トレイトがここで示したよりも有用な状況があるのは勿論ですが、そういった例を長々と議論するのはこの文書の目的から外れます。 #center(){[[前ページ>Tutorial_6]]  [[目次>Tutorial和訳]]  [[次ページ>Tutorial_8]]} ---- #comment()

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。