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..."}}
Czy istnieje uzasadniony powód, dla którego stackoverflow.com/suggested-edits/237242 nie został przesłany? Pokazuje, jak to zrobić z 2 klasami, jak pierwotnie zadano pytanie.
GlassGhost
2
Co się stanie, jeśli wiele wątków generuje zdarzenia źródłowe, czy będzie to odpowiednio synchronizowane?
Mike G
Zależy od syracji. Każdy słuchacz zostanie powiadomiony zgodnie z zamówieniem, które zarejestrował. (Przy okazji, nie rozumiem, co masz na myśli przez wiele wątków tutaj. Kod nasłuchującego zostanie wydany w tym samym wątku, który spowodował zdarzenie).
aioobe,
8
@GlassGhost: Zostało odrzucone, ponieważ było to w zasadzie całkowite przepisanie. Zmiany w odpowiedziach innych osób są dobre, jeśli naprawią literówki i formatowanie oraz zepsute linki itp., Ale nie powinny radykalnie zmieniać treści. (Niektóre wyjątki dotyczą postów oznaczonych jako „wiki społeczności”.)
cHao
1
Czy java nie ma do tego wbudowanej rzeczy? Naprawdę wolałbym robić to w abstrakcyjny sposób, a nie implementować pętli dla każdego zdarzenia.
Tomáš Zato - Przywróć Monikę
27
To, czego chcesz, to implementacja wzorca obserwatora . Możesz zrobić to sam lub użyć klas Java takich jak java.util.Observerijava.util.Observable
Throweri Catcherwewnątrz innej klasy w tym przykładzieTest
PRZYKŁAD GITHUBA PRACY JESTEM CITING Domyślnie opcja 3, aby wypróbować inne, po prostu odkomentujOptionalblok kodu klasy, którą chcesz być głównym, i ustaw tę klasę jako${Main-Class}zmienną wbuild.xmlpliku:
4 rzeczy potrzebne do rzucenia bocznego kodu:
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 Rzeczy potrzebne w pliku klasy, aby otrzymywać zdarzenia z klasy
/*_______________________________________________________________*/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: Problem polega na tym, że mainjest statyczny i nie ma czegoś takiego jak thisfunkcja statyczna. Musisz new Catcher1()gdzieś utworzyć i przekazać tę instancję. 1.5 także nie pozwalał thisw kontekście statycznym; jestem prawie pewien, że nigdy nie było dozwolone.
cHao
6
@GlassGhost: używany kod thisznajduje się w konstruktorze, a nie w main. Właśnie dlatego to działa. Przenieś do main, a gwarantuję, że nie. To właśnie ludzie próbują ci powiedzieć i jak stara się zrobić twoja odpowiedź. Nie obchodzi mnie, co jest na githubie - obchodzi mnie, co jest na SO. A to, co masz na SO, jest zepsute.
cHao
7
@GlassGhost: Nie sądzę, aby twoja odpowiedź była ogólnie nieodpowiednia. Problem widzę w nim jest to, że kod nie będzie działać jak jest - starasz się używać thisz main, które nie będą w żaden kompilacji wydanej wersji Java. Jeśli ta część znajdowała się w konstruktorze, lub jeśli została mainutworzona new Catcher1()i używana zamiast thisniej, powinna działać, nawet w wersji 1.6+.
cHao
6
@GlassGhost: „Zadeklarowana metoda staticnazywana jest metodą klasową. Metoda klasowa jest zawsze wywoływana bez odniesienia do konkretnego obiektu. Próba odwołania się do bieżącego obiektu za pomocą słowa kluczowego thislub słowa kluczowego superlub odniesienia parametrów parametrów dowolnego otoczenia deklaracja w treści metody klasy powoduje błąd czasu kompilacji. ” - JLS dla Java 5, § 8.4.3.2
cHao
31
To jeden z najdziwniejszych stylów kodu, jaki kiedykolwiek widziałem
Eric,
4
Poniższe informacje nie są dokładnie takie same, ale podobne. Szukałem fragmentu kodu, aby dodać wywołanie do metody interfejsu, ale znalazłem to pytanie, więc zdecydowałem się dodać ten fragment dla osób, które szukają go jak ja, i znalazłem to pytanie. :
Odpowiedzi:
Prawdopodobnie chcesz przyjrzeć się wzorowi obserwatora .
Oto przykładowy kod na początek:
Artykuł pokrewny: Java: Tworzenie niestandardowego zdarzenia
źródło
To, czego chcesz, to implementacja wzorca obserwatora . Możesz zrobić to sam lub użyć klas Java takich jak
java.util.Observer
ijava.util.Observable
źródło
Istnieją 3 różne sposoby skonfigurowania tego:
Thrower
wnętrzeCatcher
Catcher
wnętrzeThrower
Thrower
iCatcher
wewnątrz innej klasy w tym przykładzieTest
PRZYKŁAD GITHUBA PRACY JESTEM CITING Domyślnie opcja 3, aby wypróbować inne, po prostu odkomentuj
Optional
blok kodu klasy, którą chcesz być głównym, i ustaw tę klasę jako${Main-Class}
zmienną wbuild.xml
pliku:4 rzeczy potrzebne do rzucenia bocznego kodu:
2 Rzeczy potrzebne w pliku klasy, aby otrzymywać zdarzenia z klasy
źródło
main
jest statyczny i nie ma czegoś takiego jakthis
funkcja statyczna. Musisznew Catcher1()
gdzieś utworzyć i przekazać tę instancję. 1.5 także nie pozwalałthis
w kontekście statycznym; jestem prawie pewien, że nigdy nie było dozwolone.this
znajduje się w konstruktorze, a nie wmain
. Właśnie dlatego to działa. Przenieś domain
, a gwarantuję, że nie. To właśnie ludzie próbują ci powiedzieć i jak stara się zrobić twoja odpowiedź. Nie obchodzi mnie, co jest na githubie - obchodzi mnie, co jest na SO. A to, co masz na SO, jest zepsute.this
zmain
, które nie będą w żaden kompilacji wydanej wersji Java. Jeśli ta część znajdowała się w konstruktorze, lub jeśli zostałamain
utworzonanew Catcher1()
i używana zamiastthis
niej, powinna działać, nawet w wersji 1.6+.static
nazywana jest metodą klasową. Metoda klasowa jest zawsze wywoływana bez odniesienia do konkretnego obiektu. Próba odwołania się do bieżącego obiektu za pomocą słowa kluczowegothis
lub słowa kluczowegosuper
lub odniesienia parametrów parametrów dowolnego otoczenia deklaracja w treści metody klasy powoduje błąd czasu kompilacji. ” - JLS dla Java 5, § 8.4.3.2Poniższe informacje nie są dokładnie takie same, ale podobne. Szukałem fragmentu kodu, aby dodać wywołanie do metody interfejsu, ale znalazłem to pytanie, więc zdecydowałem się dodać ten fragment dla osób, które szukają go jak ja, i znalazłem to pytanie. :
Użycie jest następujące:
źródło