2016-10-12 1 views
1

ケースクラスDataObjectを作りたいと思います。自己参照のパラメータは特定の特性でのみ使用できますか?

case class DataObject(parameter: Double) 

私は必要に応じて機能を呼び出す機能を拡張したいと考えています。そのためには、機能を拡張するために、形質をDataObjectFunctionableに拡張したいと考えています。この機能は、DataObjectにのみ割り当てる必要があります。

trait DataObjectFunctionable { 
    this: DataObject => 
    def unimportantfunction(): Double = parameter + 1 
    protected val aFunction: AFunction 
} 

正確な実装は後で定義されるため、関数の要約はそのままにしておきます。余分な機能はDataObjectDataObjectの機能であるため、機能はDataObjectFunctionableとなるため、機能の入力タイプとしてDataObjectFunctionableとします。

trait AFunction { 
    def value(in: DataObjectFunctionable) 
} 

ここで、具体的なFunctionを定義します。これは、入力パラメータを超過したいときまで、すべて良好です。

object MyFunction extends AFunction { 
    def value(in: DataObjectFunctionable) = in.parameter + 2 
} 

ここでは、in.parameterは解決できないと言われています。何故ですか? this: DataObject =>DataObjectFunctionableunimportantfunctionと表示されているように)内にDataObjectのメンバーもいることを確認してください。この場合でも、私はMyFunctionの私の処分でparameterを持っていないのはなぜですか?それは単なる言語設計ですか、何か間違っていますか?

代わりにどうすればよいですか?私はそれを見つけた

trait DataObjectFunctionable extends DataObject { 
    this: DataObject => 
    def unimportantfunction(): Double = parameter + 1 
    protected val aFunction: AFunction 
} 

は問題を解決しますが、これは本当に行く方法ですか?

私が理解する限り、trait DataObjectFunctionable extends DataObjectは「DataObjectFunctionableの形質はDataObjectまたはそれのサブクラスによってのみ拡張することができます」を意味します。しかし、私が理解する限り、this: DataObject =>は同じことを意味します...おそらく私の問題につながった誤解があります。ところで


、これは私が望んです:

val myObject1 = new DataObject(parameter = 5) extends DataObjectFunctionable { 
    override protected val aFunction: AFunction = MyFunction 
    } 
val myObject2 = new DataObject(parameter = 5) 
myObject1.value // returns 5 
myObject2.value // that should not be possible, since myObject2 does not get the functionality. I want this to throw a compiler error 
+0

"返品エラー"を定義できますか? – Reactormonk

+0

@Reactormonk:done。編集された質問。 – Make42

+0

何とかそれは整列していません - あなたは 'DataObject'に' value'をどこに添付しますか? – Reactormonk

答えて

1

自己参照は、「プライベート継承」に似ています。 継承されたパラメータを特性に「プライベート」にしたくない場合は、自己参照ではなくDataObjectから継承させてください。

また、def param = parameterのような形で自己参照パラメータを特性から「エクスポート」することもできます。

また、注意しなければならないことは、ケースクラスを拡張しないでください。ほとんど常に悪い考えです。

+0

私は「私的継承」が正しいキーワードだと思います。あなたの最初の段落も私のアイデアでした(質問を参照)。'DataObject'はしばしば' DataObjectFunctionable'でインスタンス化され(それによって継承されます)、 'DataObjectFunctionable'は' DataObject'を継承します(その逆も継承します)。 – Make42

+0

「クラスを拡張する形質」と「形質自己参照」との違いはよく分かりません。しかし、おそらく私は別の質問としてそれをする必要があります。 – Make42

+0

'DataObject'は' DataObjectFunctionable'から継承しません。あなたが「しばしばそれを使ってインスタンス化されている」と言うとき、本当に意味することは、あなたはしばしば、DataObjectとDataObjectFunctionableを継承する他のクラス(おそらく匿名)を作成することです。それは前者を後者を決して受け継ぐことはできません。 – Dima