Как заставить мой метод принимать объекты из внешнего программного обеспечения? - PullRequest
0 голосов
/ 21 апреля 2010

У меня есть метод, который должен принимать объект обратного вызова в качестве аргумента, а затем (в тот момент, когда это необходимо) мой метод вызовет определенный метод объекта обратного вызова.

Я написал класс с именем Manager, в котором есть метод с именем addListener. В качестве аргумента для этого метода мне нужно использовать объект обратного вызова, который определяется внешним программным обеспечением. Итак, я определяю addListener следующим образом: public void addListener(Listener listener).

Конечно, Eclipse жалуется, потому что не знает, что такое Listener (потому что слушатель определяется внешним программным обеспечением). Единственная мысль, которую я знаю (должен знать) о Слушателе, это то, что у него есть метод с именем doSomething. Итак, для удовольствия Eclipse я добавляю интерфейс перед моим Manager классом:

interface Listener {
    void doSomething();
}

public class CTManager {
...

Проблема, похоже, решена, но затем я пытаюсь протестировать свое программное обеспечение. Итак, я создаю класс с именем test. В этом классе я создаю экземпляр класса Manager и пытаюсь использовать метод addListener этого экземпляра.

Я также создаю класс Listener, создаю его экземпляр и передаю экземпляр addListener. И это место, где возникает проблема. Eclipse пишет, что addListener не применимо к данному аргументу. Я думаю, это потому, что он ожидает чего-то от моего Listenr интерфейса, но получает что-то от Listener класса.

Как я могу решить эту проблему?

Ответы [ 4 ]

2 голосов
/ 21 апреля 2010

Вы на правильном пути к решению. Для того, чтобы два компонента программного обеспечения могли взаимодействовать друг с другом, эти два компонента должны согласовать заключенный между ними контракт.

Механизм обратного вызова, который вы описываете, довольно распространен. Контракт здесь - это интерфейс Listener, который ваша часть использует для вызова метода doSomething() для объекта обратного вызова и который другая часть должна реализовать, чтобы предложить действительный объект слушателя.

Способ, которым Java обрабатывает эти контакты, заключается в том, что загрузчики классов объявляют, что интерфейс одной части программного обеспечения совместим (или равен) интерфейсу, который использует другая часть.

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

Когда вы строите своего менеджера, вы также предоставляете определение интерфейса контракта, например:

com.your.program.manager.Listener

Это означает, что вам нужно будет предоставить копию файла

com/your/program/manager/Listener.java

стороне, которая строит объект обратного вызова, чтобы они могли импортировать то же определение Listener, которое использует ваш менеджер. Если обе части используют одно и то же определение, контакт сработает.

1 голос
/ 21 апреля 2010

Похоже, что созданный вами интерфейс Listener имеет имя пакета, отличное от стороннего объекта Listener, который вы пытаетесь принять в качестве аргумента.

Мое предпочтительное решение - включить стороннюю библиотеку, содержащую объект Listener, в свой путь сборки Eclipse, и тогда вы сможете напрямую ссылаться на сторонний объект.

Если есть какая-то причина, по которой вы не можете этого сделать, убедитесь, что ваш интерфейс Listener находится в том же пакете, что и сторонний класс Listener, чтобы полные имена вашего интерфейса и стороннего класса идентичны.

1 голос
/ 21 апреля 2010

Класс Listener, который вы создаете, должен реализовывать интерфейс Listener, который вы объявили параметром функции addListener ...

0 голосов
/ 21 апреля 2010

Я думаю, что это, вероятно, проблема пути сборки в Eclipse. Убедитесь, что файл JAR, содержащий класс Listener, находится в пути сборки.

Другая возможность состоит в том, что в исходном коде вашего CTManager класса вы пропускаете оператор import some.package.Listener;.

...