2011-12-27 14 views
0

visitorパターンを使用してツリーを実装したいと思います。そこで、私はメインクラスNodeと、そのクラスを拡張する他のクラスを作成しました(例えば、Node1Node2Node3)。 Nodeには、文字列とArrayListNodesがあり、これはそのノードの子のリストです。だから私は、3つの機能visit(Node1 x)で訪問者を実装し...とmainに私はすべてのノードの受け入れ呼びたい:.getClassは、特定のクラス を返すにもかかわらず、私はノード1を意味するので、これは動作しませんVisitor Patternはオブジェクトのクラスを認識しません

SomeVisitor v = new SomeVisitor(); 
Node n = makeTree(); 
Iterator<? extends Node> it = n.children.iterator(); 
while(it.hasNext()) { 
    System.out.println(it.next().getClass()); 

    it.next.accept(v); 
} 

を、2または3であり、私が手にエラーがそれがit.nextであるがタイプ ノードであるが、私は私のツリー内の任意のノードオブジェクトを持っていない、と私は visit(Node)だけvisit(Node 1,2,3)

+0

をあなたはあなたが投稿したコードのビットのバグを持っている:あなたはit.next '呼んでいます() 'を同じ繰り返しで2回繰り返します。 – toto2

答えて

0

あなたのソリューションを使用することです実装されていませんでした訪問者のパターンは、あなたがしているように見えるものではありません。

私はちょうど

これはあなたの問題である(ノード1,2,3)を訪れる訪問(ノード)を実装していませんでした。あなたはあなたが呼ぶものと同じ方法で同じインターフェースを実装しなければなりません。

また、あなたが

@JB Nizetのソリューションは似ていますが、私はそのシンプルな、それは最初から呼び出す必要がある方法でコードを書くことだと思う。

v.visit(it.next()); 

としてそれを書く必要があります

+0

acceptメソッドは、基本Nodeクラスになければなりません。しかし、サブクラスのタイプごとに1つの訪問メソッドが存在する必要があります。いくつかのサブクラスを共通の一般的な方法で訪問したい場合を除き、visit(Node)の必要はありません。 –

+0

各サブクラスがacceptメソッドをオーバーライドするためです。私の答えとウィキペディアのリンクを見てください。訪問メソッドは、異なる名前を持つこともできます:visitNode1、visitNode2、visitNode3。各サブクラスは、ビジターが訪問を受け入れるかどうかを尋ねるときに呼び出す訪問メソッドを決定します。 –

+0

それは多型の全体のポイントを破ることはありません。コールを構造化する際に、別々のメソッドを記述するのはなぜ、これを行う必要がないのですか? –

0

あなたの問題がどこにあるかを推測するのは難しいです。 wikipediaのようなサンプル実装を見てください。そこに見られるように、パターンは拡張を使用することによって実装されるのではなく、デコレーティングインタフェースを使用して実装されます。

+0

私はNodeクラスでaccept関数を実装する必要はありませんが、それを拡張するクラスだけを使用していなかったので...私はNode用に実装しようとしますが、訪問者は私は訪問(ノード1 2 3)と呼ばれることはありません...私はかなり混乱している...私は訪問者のパターンは何を知っているが、私は完全にそれを理解することはできません..答えに感謝! – exilonX

+0

@IonelMerca:実際には、 'Node'スーパークラスは必要ないかもしれません。単に 'Node1'、' Node2'と 'Node3'に' accept(SomeVisitor) 'メソッドを持つ' VisitableNode'インターフェースを実装させてください。 'SomeVisitor'は' visit(Node1) '、' visit(Node2) '、' visit(Node3) 'メソッドを持たなければなりません。 – Kai

2

visitor patternの説明を確認してください。 acceptメソッドは、基本クラスで宣言されなければならない、とそれぞれのサブクラスは、適切な訪問メソッドコールバックして上書きする必要があります

public abstract class Node { 
    public abstract void accept(Visitor v); 
} 

public class Node1 extends Node { 
    @Override 
    public void accept(Visitor v) { 
     v.visit(this); // calls visit(Node1) 
    } 
} 
関連する問題