Метод перегрузки из универсального интерфейса - PullRequest
0 голосов
/ 22 февраля 2019

Я играю с шаблоном посетителя, чтобы пересечь гетерогенную структуру объекта, и хочу перегрузить метод visit() в моем универсальном интерфейсе, чтобы по-разному обрабатывать разные подтипы.Почему в коде ниже не вызывается visit(Bar), и я могу что-нибудь сделать, чтобы это исправить?Заранее спасибо за помощь!

Стив

package test;

import java.util.ArrayList;

public class OverloadTest {

    public static void main(String[] args) {

        // Create a visitable collection
        FooCollection c = new FooCollection();

        // Add some members
        c.add(new Foo());
        c.add(new Bar());

        // Visit
        c.accept(new IVisitor<Foo>() {

            public void visit(Foo foo) {
                System.out.println("Foo");
            }

            public void visit(Bar bar) {
                System.out.println("Bar");
            }
        });
    }

    public static class Foo {
    }

    public static class Bar extends Foo {
    }

    public static interface IVisitor<T> {

        public void visit(T object);
    }

    public static class FooCollection {

        private final ArrayList<Foo> m_list = new ArrayList<>();

        public void accept(IVisitor<Foo> visitor) {
            for (Foo foo : m_list) {
                visitor.visit(foo);
            }
        }

        public void add(Foo foo) {
            m_list.add(foo);
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Это работает, если я изменяю IVisitor для включения метода для каждого желаемого типа:

public static interface IFooVisitor {
    public void visit(Foo foo);
    public void visit(Bar bar);
}

и реализую метод accept () для каждого:

public static class Foo {       
    public void accept(IFooVisitor visitor) {
        visitor.visit(this);
    }
}

public static class Bar extends Foo {
    public void accept(IFooVisitor visitor) {
        visitor.visit(this);
    }
}

Я теряю некоторую гибкостьи соедините Foo и Bar с шаблоном посетителя, но это работает.

0 голосов
/ 22 февраля 2019

Ваш посетитель в public void accept(IVisitor<Foo> visitor) реализует IVisitor<Foo>, поэтому единственный видимый метод - public void visit(Foo foo).Один из способов исправить это - оставить универсальный IVisitor (удалив <Foo> из объявления интерфейса).Метод на нем становится:

public void visit(Object object);

Другой вариант - изменить метод accept на:

public void accept(IVisitor<Object> visitor) {
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...