次の Scala クラスのレイアウトを考えています。私はアイテムを表す基本的な特性を持っています - 名前、重量を照会し、次のようなメソッドを呼び出すことによっていくつかのオブジェクト固有のことを行うことができる不変オブジェクトであるべきもののインターフェースですequip
:
trait Item {
def name: String
def weight: Int
def equip // ... more abstract methods
}
ケースクラスを手動で作成して実装を作成できますItem
が、ある種の「辞書」ベースのアイテムが必要です-つまり、静的マップは型IDから値へのマッピングを保持しname
、weight
メソッドは格納された型で辞書を照会するだけですID:
object Weapon {
final val NameDict = Map(1 -> "short sword", 2 -> "long sword")
final val WeightDict = Map(1 -> 15, 2 -> 30)
}
case class Weapon(typ: Int) extends Item {
import Weapon._
def name = NameDict(typ)
def weight = WeightDict(typ)
def equip = ... // implementation for weapon
}
ここまでは順調ですね。Weapon(1)
「ショート ソード」のアイテム オブジェクトを参照するために使用できます。Armor
ただし、まったく同じ実装を使用するname
がweight
、完全に異なるequip
他の抽象メソッド実装を使用するなどの他の項目タイプにも同じ基本原則が適用されます。次に例を示します。
object Armor {
final val NameDict = Map(3 -> "bronze armor", 4 -> "iron armor")
final val WeightDict = Map(3 -> 100, 4 -> 200)
}
case class Armor(typ: Int) extends Item {
import Armor._
def name = NameDict(typ)
def weight = WeightDict(typ)
def equip = ... // implementation for armor
}
にかなり似てWeapon
いますね。共通のパターン (つまり、コンパニオン オブジェクト ディクショナリと共通のtyp
値でのルックアップの実装) を次のように除外したいと思います。
abstract class DictionaryItem(typ: Int) extends Item {
def name = ???.NameDict(typ)
def weight = ???.WeightDict(typ)
}
object Weapon {
final val NameDict = Map(1 -> "sword", 2 -> "bow")
final val WeightDict = Map(1 -> 15, 2 -> 30)
}
case class Weapon(typ: Int) extends DictionaryItem(typ) {
def equip = ... // implementation for weapon
}
しかしWeapon.NameDict
、親クラスから子のコンパニオン オブジェクト ( など) を参照するには???.NameDict(typ)
どうすればよいですか? そのような問題に対するより良い、より Scala 風のアプローチはありますか?