質問
Scalaの特性について誰か説明してください。抽象クラスを拡張することに対する特性の利点は何ですか?
解決
簡単な答えは、複数の特性を使用できることです-それらは「積み重ね可能」です。また、トレイトにはコンストラクターパラメーターを指定できません。
これは、特性がどのように積み重ねられるかです。特性の順序が重要であることに注意してください。彼らは互いに右から左に呼び出します。
class Ball {
def properties(): List[String] = List()
override def toString() = "It's a" +
properties.mkString(" ", ", ", " ") +
"ball"
}
trait Red extends Ball {
override def properties() = super.properties ::: List("red")
}
trait Shiny extends Ball {
override def properties() = super.properties ::: List("shiny")
}
object Balls {
def main(args: Array[String]) {
val myBall = new Ball with Shiny with Red
println(myBall) // It's a shiny, red ball
}
}
他のヒント
このサイトは、特性の使用の良い例を示しています。特性の大きな利点の1つは、複数の特性を拡張できますが、抽象クラスは1つだけであるということです。特性は、多重継承で多くの問題を解決しますが、コードの再利用を許可します。
ルビーを知っている場合、特性はミックスインに似ています
package ground.learning.scala.traits
/**
* Created by Mohan on 31/08/2014.
*
* Stacks are layered one top of another, when moving from Left -> Right,
* Right most will be at the top layer, and receives method call.
*/
object TraitMain {
def main(args: Array[String]) {
val strangers: List[NoEmotion] = List(
new Stranger("Ray") with NoEmotion,
new Stranger("Ray") with Bad,
new Stranger("Ray") with Good,
new Stranger("Ray") with Good with Bad,
new Stranger("Ray") with Bad with Good)
println(strangers.map(_.hi + "\n"))
}
}
trait NoEmotion {
def value: String
def hi = "I am " + value
}
trait Good extends NoEmotion {
override def hi = "I am " + value + ", It is a beautiful day!"
}
trait Bad extends NoEmotion {
override def hi = "I am " + value + ", It is a bad day!"
}
case class Stranger(value: String) {
}
Output : List(I am Ray , I am Ray, It is a bad day! , I am Ray, It is a beautiful day! , I am Ray, It is a bad day! , I am Ray, It is a beautiful day! )
これは私が見た中で最高の例です
Scalaの実際:構成する特性–レゴスタイル: http://gleichmann.wordpress。 com / 2009/10/21 / scala-in-practice-composing-traits-lego-style /
class Shuttle extends Spacecraft with ControlCabin with PulseEngine{
val maxPulse = 10
def increaseSpeed = speedUp
}
Traitsは、機能をクラスに混在させるのに役立ちます。 http://scalatest.org/ をご覧ください。さまざまなドメイン固有言語(DSL)をテストクラスに混在させる方法に注意してください。クイックスタートガイドを見て、ScalatestでサポートされているDSLのいくつかを見てください( http://scalatest.org/quick_start)
Javaのインターフェースと同様に、トレイトは、サポートされているメソッドのシグネチャを指定することでオブジェクトタイプを定義するために使用されます。
Javaとは異なり、Scalaでは特性を部分的に実装できます。つまり、一部のメソッドのデフォルト実装を定義することが可能です。
クラスとは対照的に、トレイトにはコンストラクターパラメーターがない場合があります。 特性はクラスに似ていますが、クラスが具体的な値と実装を提供できる関数とフィールドのインターフェースを定義します。
トレイトは、他のトレイトまたはクラスから継承できます。
本のウェブサイトから引用しています Scalaでのプログラミング、初版、より具体的には" 特性化するか、特性化しないか"第12章から。
再利用可能な動作のコレクションを実装するたびに、特性または抽象クラスのどちらを使用するかを決定する必要があります。確固たるルールはありませんが、このセクションには考慮すべきガイドラインがいくつか含まれています。
動作が再利用されない場合は、具体的なクラスにします。結局、再利用可能な動作ではありません。
複数の無関係なクラスで再利用される可能性がある場合は、特性にします。クラス階層のさまざまな部分に混合できるのは特性のみです。
形質に関する上記のリンクにはもう少し情報があります。セクション全体を読むことをお勧めします。これがお役に立てば幸いです。