2016-07-31 18 views
1

IDを表すオブジェクトにオブジェクトがあります。スカラ値クラス多重継承

ChairId、TableId、LampIdとしましょう。 GenericIdから継承してほしい。そして私は電話したいと思っていますdef f(x: GenericId) = x.id

私は彼らに1つだけid: Stringを保持したいので、私はそれらをAnyValに拡張したいと思います。場合しかし

sealed abstract class GenericId(val id: String) 
final case class ChairId(override val id: String) extends GenericId(id) 
final case class TableId(override val id: String) extends GenericId(id 

と私:

また、私は私の特定のID、すなわちを生成する機能generateを提供するために、各タイプの希望私はこれを入力したChairId.generate()

のようなものを入力したいですGenericIdはAnyValから継承していましたが、これまで運がなかったのです。/また、GenericIdを特性にして、GenericIdでAnyValを拡張するようにしましたが、コンパイルも行いません:/

Anot彼女のことTableId.generate()私はコンパイルオブジェクトを提供することができますちょうど関数generateとは、基本的に私の問題を解決するが、コンパニオンオブジェクトを定義せずに解決する可能性があるのだろうか? (つまり、暗黙を通じて何らかの形で)コンパイルされないコードを提供するために、コメントに関する

//編集

(と私はしたいと思います):

sealed abstract class AbstractId(val id: String) extends AnyVal 
final case class CatId(override val id: String) extends AbstractId(id) 
final case class DogId(override val id: String) extends AbstractId(id) 
+0

私はあなたがここで何を求めているか完全にはわかりません。複数の質問がある場合は、複数のStack Overflow質問に分割することができます。 –

+0

試したことのコードとコンパイルエラーを含めてください。それが助けになると思います。 –

答えて

3

バリュークラスはこのように動作することはできませんいくつかの理由。

まず、documentationから、値クラスは他のクラスで拡張できないため、AbstractIdAnyValを拡張できません。 (Limitation #7

scala> abstract class AbstractId(val id: String) extends AnyVal 
<console>:10: error: `abstract' modifier cannot be used with value classes 
     abstract class AbstractId(val id: String) extends AnyVal 
        ^

第二に、あなたがAbstractId形質を行い、このような他のIDを定義しても場合:

final case class DogId(val id: String) extends AnyVal with AbstractId 

を..値クラスの使用法はあなたに合わないでしょうクラス自体がまだ割り当てられているためです。 allocation summaryを参照してください

ときに値クラスが実際にインスタンス化される:値クラスが別の型として扱われ

  1. 値クラスは配列に割り当てられます。
  2. パターンマッチングなどの実行時型テストを実行します。あなたの疑問を明確にする可能性があるvalue classes SIPから
+0

あなたは数秒間私を打つ:) – pedrofurla

1

いくつかの引用符:

バリュークラス...

  1. は...正確に一つのパブリック、型が値クラスではありませんヴァル パラメータを持つ唯一のプライマリコンストラクタを持っている必要があります。

  2. ...他のクラスでは拡張できません。

1を1として、それは抽象的にすることはできません。あなたのエンコーディングは動作しません。

別の注意点があります:

値クラスのみ普遍的な特質を拡張することができと 自体を拡張することはできませんが。普遍的な形質はAnyを拡張する特性であり、defはメンバとしてのみ存在し、初期化はしません。ユニバーサル特性により、ベーシッククラス のメソッドの継承が可能になりますが、割り当てのオーバーヘッドは になります。心の中ですべてのことで

、あなたの最後のスニペットに基づいて、これはうまくいくかもしれない:

sealed trait AbstractId extends Any { def id: String } 
final case class CatId(id: String) extends AnyVal with AbstractId 
final case class DogId(id: String) extends AnyVal with AbstractId 

をしかし、あなたがAbstractIdとしてCATIDとDogIdを使用したい場合は割り当てがのみ発生に注意してください。理解を深めるために、私はSIPを読むことをお勧めします。