Шаблон посетителя принимает не распознающий класс объекта - PullRequest
0 голосов
/ 27 декабря 2011

Я хочу использовать шаблон посетителя для реализации дерева. Поэтому я создал основной класс Node и другие классы, расширяющие этот класс (например, Node1, Node2, Node3). В Node у меня есть строка и ArrayList из Nodes, который является списком дочерних элементов этого узла. Поэтому я реализовал посетителя с 3 функциями visit(Node1 x), ... и в main я хочу вызвать accept каждого узла:

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); 
}

это не работает, потому что даже если .getClass возвращает определенный класс Я имею в виду Узел 1, 2 или 3, и ошибка, которую я получаю, заключается в том, что it.next является типом узел, но у меня нет ни одного объекта узла в моем дереве, и я не реализовал visit(Node) просто visit(Node 1,2,3)

Ответы [ 3 ]

2 голосов
/ 27 декабря 2011

Проверьте описание шаблона посетителя .Метод 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)
    }
}
0 голосов
/ 27 декабря 2011

Трудно догадаться, где твоя проблема.Вы должны взглянуть на пример реализации, такой как в wikipedia .Как вы увидите, шаблон реализуется не с помощью расширения, а с помощью украшающих интерфейсов.

0 голосов
/ 27 декабря 2011

Ваше решение состоит в том, чтобы использовать шаблон посетителя, а это не то, что вы делаете.

Я не реализовал посещение (узел), просто посещение (узел 1,2,3)

Это ваша проблема.Вы должны реализовать тот же интерфейс с тем же методом, который вы называете.

Также вам нужно написать его как

v.visit(it.next());

@ Решение JB Nizet похоже, но я думаю, что оно прощенаписать код так, как его нужно вызывать с самого начала.

...