2012-05-04 8 views
0

APartまたはProject)のサブクラスの追加インスタンスを作成するために、スーパークラス(Tree[A])からサブクラスのコンストラクタを呼び出す必要があります。 Listのようなものがあるので、中間メソッドnewChildを作ることの混乱よりも良い方法がなければならないようです。 CanBuildFromがこの問題に対処するかもしれないと聞いたことがあります。作業コードからスーパークラス内のメンバーにScalaサブクラスコンストラクタを使用するにはどうすればよいですか?

エキス:

abstract class Tree[A](parent: Option[A], key: Int) { 
    protected def newChild(aKey: Int): A 
    lazy val children: List[A] = childrenOf.map(newChild(_)) 
    ... 
    } 

case class Part(parent: Option[Part], key: Int) extends Tree[Part](parent, key) { 
    protected def newChild(aKey: Int) = Part(Some(this), aKey) 
    ... 
    } 

case class Project(parent: Option[Project], key: Int) extends Tree[Project](parent, key) { 
    protected def newChild(aKey: Int) = Project(Some(this), aKey) 
    ... 
    } 
... 
"*" #> <ul>{Part(None, pKey).expandAsHtml}</ul> 

スーパークラス内でメンバーのScalaのサブクラスのコンストラクタを使用するより良い方法は何ですか?

+5

そのロジックを反転して、スーパークラスのコンストラクタをサブクラスのコンストラクタから呼び出すべきではありませんか?これはスーパークラスではなく、何をするかを知っているサブクラスです。 – geekosaur

+1

私は混乱しています。このコードはコンパイルされるかどうか?コンパイルすると、どのコードがコンパイルされませんか?エラーメッセージ(コード行と列インジケータを含む完全なエラーメッセージ)は何ですか? –

+0

@DCSは「作業コードから抽出」を追加しました。 –

答えて

1

あなたはそれを後ろ向きに見ています。オブジェクトが作成されると、そのコンストラクタが呼び出されます。このスーパークラスのコンストラクタには、デフォルトまたは明示的な呼び出しのいずれかによって委譲されます。 スーパークラスのコンストラクタを最初に呼び出すサブクラスのコンストラクタであるため、スーパークラスのコンストラクタからサブクラスのコンストラクタを呼び出すことはできません。

あなたのロジックを見て、サブクラスが知られている方法は、です。は直接インスタンス化されています。スーパークラスが何らかの種類のパラメータとしてインスタンス化されているわけではなく、スーパークラスがインスタンス化のステップとしてインスタンス化され、スーパークラスはそれ自身の構造について知っているだけで、サブクラスの詳細はトリガーされたサブクラスのコンストラクタに残されますスーパークラス。

+0

スーパークラスの( 'Tree')コンストラクタは、拡張ラインで呼び出されると思います。 'children'の値は、サブクラスの新しいインスタンス(' Project'または 'Part'のいずれか)をインスタンス化します。 'newChild'はこの作業をするために作られましたが、それを実装するためにはサブクラスが必要です。サブクラスの別のインスタンスのコンストラクタを呼び出す方法があるはずです。 あなたの答えは、実行できない、または実行してはならないことを意味しますか? –

+0

正確ではありません。 'extend'は、すべてのサブクラスコンストラクタにスーパークラスコンストラクタがまだ存在しない場合に、そのコンストラクタの呼び出しを追加するよう指示します。特定のサブクラスインスタンスの構築時に、別の類似した/兄弟インスタンスの作成をトリガーしたいと言っていますか?いずれにしても、これは依然としてスーパークラスではなくサブクラスに属します。 – geekosaur

+0

各インスタンスには 'List [A]'型の 'val children 'があ​​ります。リスト内の各インスタンスは 'children'リストを含んでいます...スーパークラスの目的は、サブクラスからツリーの実装の詳細を(List [A]'として)削除することですスーパークラスの共通の場所に移動します。 –

0

これを達成する唯一の方法は、リフレクションを使用することです。

私はここにチュートリアルが見つかりました: http://www.heimetli.ch/java/create-new-instance.html

この方法で、あなたのスーパークラス内のサブクラスのコンストラクタを取得し、あなたのサブクラスの新しいインスタンスを作成し、それを呼び出すことができます。

しかし、何らかの形で、サブクラスが特定の引数リストを持つコンストラクタを実装していることを確認する必要があります。

関連する問題