首先來介紹一下什麼是監聽器:
監聽器-就是一個實現待定接口的普通Java程序,此程序專門用於監聽另外一個類的方法調用。
這是使用觀察者模式的。
什麼是觀察者模式:
定義對象間一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對像都得到通知自動更新。
示例:
GUI編程中的addXxxxListener都是觀察者模式。
比如為按鈕點擊添加監聽事件,為鍵盤添加監聽等等…
觀察者模式的三個重要類:
被監聽的事件源,也就是我們在使用的對象。
註冊的那個監聽器,是專門用來監聽當前使用的對象的。
事件對象Event也就是被監聽的那個對象!
我們先來看一個簡單版的,自己寫的監聽器。
簡單版:
有事件源,和監聽器,測試類.
Event等下一個完整版實現.
開發步驟:
第一步:實現一個需要被監聽的類Person.
第二步:實現一個監聽接口IPersonRunListener。
第三步:在Person類中,提供一個方法(或者多個,我在這裡提供了2個方法)用於註冊IPersonRunListener類,即addBefore和addAfter
第四步:必須要在Person類中維護IPersonRunListener類的實例。
第五步:在調用person.run方法時,判斷IPersonRunListener是否為null,如果不為null則調用它的fighting方法。
第六步:在Demo類中,實例化Person,並註冊一個監聽。
Person:
package cn.hncu.designPattern1;public class Person { private String name; private IPersonRunListener listener1; private IPersonRunListener listener2; public Person(String name) { super(); this.name = name; } public void run(){ if(listener1!=null){ listener1.fighting(); } System.out.println(name+"正在跑..."); if(listener2!=null){ listener2.fighting(); } } public void addBefore(IPersonRunListener listener){ this.listener1=listener; } public void addAfter(IPersonRunListener listener){ this.listener2=listener; }}interface IPersonRunListener{ public void fighting();}Demo
package cn.hncu.designPattern1;public class Demo { public static void main(String[] args) { Person person = new Person("張三"); IPersonRunListener listener = new IPersonRunListener() { @Override public void fighting() { //這裡可以做很多事,不是只能輸出哦//不過由於還沒寫Event對象,所以拿不到是誰調用的System.out.println("先做好準備工作..."); } }; person.addBefore(listener); A a = new A(); person.addAfter(a); person.run(); }}class A implements IPersonRunListener{ @Override public void fighting() { //這裡可以做很多事,不是只能輸出哦//不過由於還沒寫Event對象,所以拿不到是誰調用的System.out.println("跑完了,休息休息..."); } }輸出:
完整版添加事件源:
在這里相對前面的增加了一個Event-事件對象.算是完整版的了。
開發步驟:
第一步:在前頁的基礎上繼續添加一個PersonEvent類(注意我說是類不是接口),代表事件對像。
第二步:給PersonEvent對像,添加一個Person屬性,用以標識事件源對像。
第三步:修改PersonListener接口的fighting方法,讓它接收一個PersonEvent參數。
第四步:在Person類run方法中,如果判斷PersonListener屬性不為空,則在調用fighting方法,實例化PersonEvent並傳給fighting方法。
第五步:在main方法中,通過PersonEvent的getSource方法測試是否是同一個對像。
Person.java
package cn.hncu.designPattern2;public class Person { private String name; private IPersonRunListener listener; public Person(String name) { super(); this.name = name; } public void run(){ System.out.println(name+"開始跑了.."); if(listener!=null){ listener.fighting(new PersonEvent(this)); } } public void addPersonListener(IPersonRunListener listener){ this.listener=listener; } public String getName(){ return name; } @Override public String toString() { return "Person [name=" + name + ", listener=" + listener + "]"; }}interface IPersonRunListener { public void fighting(PersonEvent pe);}class PersonEvent{ Person p = null; public PersonEvent(Person p) { this.p = p; } public String getName(){ return p.getName(); } public Object getSource(){ return p; }}//我們還可以寫一個幫我們實現了接口的基本類//裡面寫我們通用的模板,如果我們繼承這個類,我們就可以不寫了。 //有功能不一樣的地方,我們就自己寫,覆蓋這個類的方法class DefaultCatListener implements IPersonRunListener { @Override public void fighting(PersonEvent pe) { System.out.println("默認的動作..."); }}Demo.java
package cn.hncu.designPattern2;public class Demo { public static void main(String[] args) { Person p1 = new Person("張三"); Person p2 = new Person("Jack"); IPersonRunListener listener = new IPersonRunListener() { @Override public void fighting(PersonEvent pe) { System.out.println(pe.getSource()+"已經跑完了..."); if(pe.getName().equals("張三")){ System.out.println(pe.getName()+"跑到了第一名..."); } } }; p1.addPersonListener(listener); p2.addPersonListener(listener); p1.run(); p2.run(); Person p3 = new Person("李四"); p3.addPersonListener(new DefaultCatListener()); p3.run(); }}演示結果:
基本上的原理就是這些了,裡面事件的輸出你換成你需要的動作就可以實現你想要的功能,添加一個監聽,就可以在run方法之前或者之後調用自己想要調用的方法,做自己想做的動作!
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。