2017-12-12 9 views
0

共通基底​​から派生する約のクラス階層を定義したいと思います。型は、this oneのようなAST階層内のノードを記述しています。私はの線に沿って何かをしたいと思います:多くのケースクラスを持つクラス階層の共通コピーを定義します

trait Base { 
    def doCopy: Base 
} 

trait CloneSelf[T <: CloneSelf[T]] extends Base { 
    self: T => 

    def copy(): T 
    override def doCopy: T = copy() 
} 


case class CaseA(a: String) extends Base with CloneSelf[CaseA] 

case class CaseB(b: Int) extends Base with CloneSelf[CaseB] 

copyの存在が自動的にコピーを定義することからcase classesを防ぐため、これは、エラーになります。 「クローン」を実装する方法はありますかのcase classesを使用していますか?

答えて

1

私は、共通のベースから派生した約100のケースクラスを持つクラス階層を定義したいと考えています。

あなたは絶対にそれを避けるためにパターンを見つける必要がありますか?あなたはとにかくこれを実行したい場合は... ducktypingをお試しください:

trait CloneSelf[T <: {def copy(): T}] { 
    self: T => 
    override def doCopy: T = copy() 
} 

私は今テストすることはできませんので、これはおそらくコンパイルされませんが、あなたは一般的なアイデアを自分でそれを把握することができます!

編集:

100のサブクラスを持つことが悪である理由:インスタンスがBaseからBaseCloningに社名を変更するためにあなたは、基本クラスの1つの変更を行い想像 - (あなたはすべての子供のクラスでそれを変更する必要があります> 100回の変更)。あなたは、それはあなたがあなたのクラスで何をしたいかに依存しないようcreationnal構造パターンチェックする方法

:工場、ビルダー、プロトタイプ、フライ級を、常にどのくらいの仕事意志」について考える...複合基本クラスで何かを変更すれば、それはすべての子供に影響を及ぼしますか?

+0

これを避けるために階層を設計する方法はいくつかありますが、それでも自動コピーは得られますか? (そしてあなたはこれをやって何が悪いのかを詳しく調べることができますか?) – Suma

+0

"ベースクラッシュに1回の変更を行うと想像してください"。私はIDEを使用しているので、彼の理由を見ることができないか、これを検索して置き換えます。したがって、いくつのクラスが重要ですか。これが邪悪である重大な理由はありますか?基本クラスの通常の変更では、変更を継承するだけで派生クラスの何かを変更する必要はありません。 – Suma

+1

"あなたはすべての子クラスでそれを変更する必要があります"。 。 。またはあなたのIDEがあなたのためにそれをさせる。 – adrice727

0

それぞれを定義していることが分かりました。case classは、各クラスを定義するより実際にはCloneSelfから継承されています。コードは次のようになります。

trait Base { 
    def doCopy: Base 
} 

case class CaseA(a: String) extends Base { 
    def doCopy = copy() 
} 

case class CaseB(b: Int) extends Base { 
    def doCopy = copy() 
} 

私はそのためCaseA("a").doCopyの静的な型、すなわちCaseA("a").copy()CaseAのと同じであり、オーバーライドされたメソッドの明示的な型なしタイプは、コンパイラによって推測されることを知って驚きました、ないBase。それぞれcase classの明示的な型を追加するほうが明らかでしょうが、これはそれぞれに同じ行をコピーして貼り付けるのに比べて多くの作業が必要になります。それほど重要ではありません。case classタイプでコピーすると、copy()も使用できます。私がを持っているときだけですdoCopyが必要なので、def doCopy: Base = copy()のように宣言すればほとんど害はありません。

+0

メソッドの名前を 'clone'とし、' scala.Cloneable'( 'java.lang.Cloneable'を拡張)を拡張することを考えてみてください。 –

+0

私はこの例をシンプルにしたいと思っていました。クローンをオーバーライドすることは、私がここで避けたかった独自の特徴を持っています。少なくともJavaでは、Scalaではこれが違うのですか? – Suma

+0

私はそれが違うとは言いません。私はあなたのチームの新しい開発者であれば、 'doCopy'と' clone'がどう違うのだろうと思っています。 –

関連する問題