import java.util.*;// An interface to be implemented by everyone interested in "Hello" eventsinterfaceHelloListener{void someoneSaidHello();}// Someone who says "Hello"classInitiater{privateList<HelloListener> listeners =newArrayList<HelloListener>();publicvoid addListener(HelloListener toAdd){
listeners.add(toAdd);}publicvoid sayHello(){System.out.println("Hello!!");// Notify everybody that may be interested.for(HelloListener hl : listeners)
hl.someoneSaidHello();}}// Someone interested in "Hello" eventsclassResponderimplementsHelloListener{@Overridepublicvoid someoneSaidHello(){System.out.println("Hello there...");}}classTest{publicstaticvoid main(String[] args){Initiater initiater =newInitiater();Responder responder =newResponder();
initiater.addListener(responder);
initiater.sayHello();// Prints "Hello!!!" and "Hello there..."}}
Есть ли законная причина, по которой stackoverflow.com/suggested-edits/237242 не прошел? Это показывает, как сделать это с 2 классами, как первоначально заданный вопрос.
GlassGhost
2
Что, если несколько потоков генерируют исходные события, будет ли это правильно синхронизировано?
Майк Дж
Зависит от сируации. Каждый слушатель будет уведомлен в соответствии с порядком их регистрации. (Кстати, я не понимаю, что вы подразумеваете под несколькими потоками здесь. Код слушателя будет задействован в том же потоке, который вызвал событие.)
aioobe
8
@GlassGhost: он был отклонен, потому что это было в основном полное переписывание. Правки чужого ответа хороши, если они исправляют опечатки, форматирование и неработающие ссылки и т. Д., Но они не должны радикально изменять содержимое. (Некоторые исключения применяются к сообщениям с пометкой «Вики сообщества».)
cHao
1
У java нет встроенной вещи для этого? Я действительно предпочел бы делать это в абстрактном паттерне, а не реализовывать цикл for для каждого события.
Томаш Зато - Восстановить Монику
27
То, что вы хотите, это реализация шаблона наблюдателя . Вы можете сделать это самостоятельно полностью или использовать Java-классы, такие как java.util.Observerиjava.util.Observable
Throwerи Catcherвнутри другого класса в этом примереTest
ПРИМЕР РАБОЧЕГО GITHUB I CITING По умолчанию используется вариант 3, чтобы попробовать остальные, просто раскомментируйтеOptionalблок кода "" класса, которым вы хотите быть основным, и установите этот класс в качестве${Main-Class}переменной вbuild.xmlфайле:
4 Вещи, необходимые для бросания кода стороны:
import java.util.*;//import of java.util.event//Declaration of the event's interface type, OR import of the interface,//OR declared somewhere else in the packageinterfaceThrowListener{publicvoidCatch();}/*_____________________________________________________________*/classThrower{//list of catchers & corresponding function to add/remove them in the listList<ThrowListener> listeners =newArrayList<ThrowListener>();publicvoid addThrowListener(ThrowListener toAdd){ listeners.add(toAdd);}//Set of functions that Throw Events.publicvoidThrow(){for(ThrowListener hl : listeners) hl.Catch();System.out.println("Something thrown");}////Optional: 2 things to send events to a class that is a member of the current class... go to github link to see this code ...}
2 Вещи, необходимые в файле класса для получения событий из класса
/*_______________________________________________________________*/classCatcherimplementsThrowListener{//implement added to class//Set of @Override functions that Catch Events@OverridepublicvoidCatch(){System.out.println("I caught something!!");}////Optional: 2 things to receive events from a class that is a member of the current class... go to github link to see this code ...}
@GlassGhost: проблема в том, что mainон статический, а thisв статической функции такого нет . Вам нужно создать new Catcher1()где-нибудь и передать этот экземпляр вместо. 1.5 также не допускается thisв статическом контексте; Я уверен, что это никогда не было разрешено.
Чао
6
@GlassGhost: код, который используется thisв конструкторе, а не в main. Вот почему это работает. Переместите его main, и я гарантирую, что не будет. Это то, что люди пытаются вам сказать, и что ваш ответ пытается сделать. Мне наплевать, что на github - мне все равно, что на SO. А то, что у тебя на ТА, сломано.
Чао
7
@GlassGhost: я не думаю, что ваш ответ в целом неадекватен. Проблема я вижу с ним в том , что код не будет работать как это - вы пытаетесь использовать thisс main, который не будет компилироваться в любой выпущенной версии Java. Если бы эта часть была в конструкторе, или если она была mainсоздана new Catcher1()и использовала ее вместо this, она должна работать, даже в 1.6+.
Цао
6
@GlassGhost: "Объявленный метод staticназывается методом класса. Метод класса всегда вызывается без ссылки на конкретный объект. Попытка обратиться к текущему объекту с помощью ключевого слова thisили ключевого слова superили для ссылки на параметры типа любого окружения объявление в теле метода класса приводит к ошибке времени компиляции. " - JLS для Java 5, §8.4.3.2
cHao
31
Это один из самых странных стилей кода, которые я когда-либо видел
Eric
4
Следующее не совсем то же самое, но похоже, я искал фрагмент, чтобы добавить вызов метода интерфейса, но нашел этот вопрос, поэтому я решил добавить этот фрагмент для тех, кто искал его, как я, и нашел этот вопрос. :
Ответы:
Вы, вероятно, хотите посмотреть на паттерн наблюдателя .
Вот пример кода, чтобы начать работу:
Связанная статья: Java: создание пользовательского события
источник
То, что вы хотите, это реализация шаблона наблюдателя . Вы можете сделать это самостоятельно полностью или использовать Java-классы, такие как
java.util.Observer
иjava.util.Observable
источник
Есть 3 различных способа настроить это:
Thrower
ВнутриCatcher
Catcher
ВнутриThrower
Thrower
иCatcher
внутри другого класса в этом примереTest
ПРИМЕР РАБОЧЕГО GITHUB I CITING По умолчанию используется вариант 3, чтобы попробовать остальные, просто раскомментируйте
Optional
блок кода "" класса, которым вы хотите быть основным, и установите этот класс в качестве${Main-Class}
переменной вbuild.xml
файле:4 Вещи, необходимые для бросания кода стороны:
2 Вещи, необходимые в файле класса для получения событий из класса
источник
main
он статический, аthis
в статической функции такого нет . Вам нужно создатьnew Catcher1()
где-нибудь и передать этот экземпляр вместо. 1.5 также не допускаетсяthis
в статическом контексте; Я уверен, что это никогда не было разрешено.this
в конструкторе, а не вmain
. Вот почему это работает. Переместите егоmain
, и я гарантирую, что не будет. Это то, что люди пытаются вам сказать, и что ваш ответ пытается сделать. Мне наплевать, что на github - мне все равно, что на SO. А то, что у тебя на ТА, сломано.this
сmain
, который не будет компилироваться в любой выпущенной версии Java. Если бы эта часть была в конструкторе, или если она былаmain
созданаnew Catcher1()
и использовала ее вместоthis
, она должна работать, даже в 1.6+.static
называется методом класса. Метод класса всегда вызывается без ссылки на конкретный объект. Попытка обратиться к текущему объекту с помощью ключевого словаthis
или ключевого словаsuper
или для ссылки на параметры типа любого окружения объявление в теле метода класса приводит к ошибке времени компиляции. " - JLS для Java 5, §8.4.3.2Следующее не совсем то же самое, но похоже, я искал фрагмент, чтобы добавить вызов метода интерфейса, но нашел этот вопрос, поэтому я решил добавить этот фрагмент для тех, кто искал его, как я, и нашел этот вопрос. :
Использование заключается в следующем:
источник