事件监听机制——Java vs. C#
C#语言类似Java,但两者之间的差别还是显而易见的,比如下面要说到的——事件监听机制。
Java的事件监听机制
Java中的事件监听是整个Java消息传递的基础和关键。其中涉及三类对象:事件源(Event Source)、事件(Event)、事件监听器(Event Listener)。
- 事件源:事件发生的场所,通常就是各个组件,比如一个按钮,或者编辑框等。
- 事件:描述事件源状态改变的对象。
- 事件监听器:负责监听事件源所发生的事件,并对各种事件做出相应的响应。
下面来看一个完整模型的demo:
/*
* 事件
*/
public interface IEvent {
void setEventListener(IEventListener arg);
boolean ClickButton();
boolean MoveMouse();
}
/*
* 事件监听器,调用事件处理器
*/
public interface IEventListener {
void doEvent(IEvent arg);
}
/*
* 事件源:事件发生的地点
*/
public class EventSource implements IEvent{
private IEventListener mEventListener;
boolean button;
boolean mouse;
//注册监听器
@Override
public void setEventListener(IEventListener arg){
mEventListener = arg;
}
//触发事件
public void mouseEventHappened(){
mouse = true;
mEventListener.doEvent(this);
}
@Override
public boolean ClickButton() {
return button;
// TODO Auto-generated method stub
}
@Override
public boolean MoveMouse() {
// TODO Auto-generated method stub
return mouse;
}
}
public class EventSource2 implements IEvent {
private IEventListener ml;
boolean button;
boolean mouse;
@Override
public void setEventListener(IEventListener arg) {
ml = arg;
}
@Override
public boolean ClickButton() {
// TODO Auto-generated method stub
return button;
}
@Override
public boolean MoveMouse() {
// TODO Auto-generated method stub
return mouse;
}
// 触发事件
public void buttonEventHappened() {
button = true;
ml.doEvent(this);
}
}
public class Test {
public static void main(String[] args) {
// 事件源(被监听的对象)
EventSource m1 = new EventSource();
EventSource2 m2 = new EventSource2();
// 监听器
IEventListener mEventListener = new IEventListener() {
@Override
public void doEvent(IEvent arg) {
if (true == arg.ClickButton()) {
System.out.println("你点击了按钮");
}else if(true == arg.MoveMouse()){
System.out.println("你移动了鼠标");
}
}
};
// 注册监听器到事件源
m1.setEventListener(mEventListener);
m1.mouseEventHappened();
// 注册监听器到事件源
m2.setEventListener(mEventListener);
m2.buttonEventHappened();
}
}
C# 事件监听
对于熟悉Java的小伙伴,第一次接触 C# 的委托(delegate)和事件(event)可能会比较困惑,其实这跟Java的监听、事件是等同的,只是表述上不同罢了。委托其实就是“方法模板”,就好像“类”是“对象”的模板一样。
委托+事件是观察者模式的一个典型例子,所谓的委托其实就是观察者,它会关心某种事件,一旦这种事件被触发,这个观察者就会行动。
事件的声明过程:
- 存在已经声明的事件委托,该委托位于 namespace 下,可全局访问;
- 在数据类型中利用event和事件委托来声明事件,并声明事件触发方法;
- 事件绑定,利用事件声明的对象实例,声明符合委托签名的方法,利用 += 或 -= 来进行事件的绑定和解除;
- 事件触发,代码利用事件声明中的触发事件的方法即可。
用 C# 实现的事件监听的demo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Event
{
class Program
{
static void Main(string[] args)
{
myChangedEvent mce = new myChangedEvent();
myEventListener mel = new myEventListener(mce);
mce.ToString();
mel.detach();
mce.ToString();
}
}
public delegate void myEventHandler(object s,EventArgs e); //声明自定义的事件委托,用来执行事件的声明,和处理方法的传递
class myChangedEvent
{
public event myEventHandler Changed; //利用委托来声明事件
protected virtual void OnChanged(EventArgs e) //声明事件触发的方法
{
if (Changed != null)
Changed(this, e); //触发事件
}
public override string ToString()
{
OnChanged(EventArgs.Empty); //调用事件触发方法
return "执行ToString";
}
}
class myEventListener //声明事件监听的类型,并为以上声明事件传入处理方法
{
private myChangedEvent mce;
public myEventListener(myChangedEvent Mce)
{
mce = Mce; //利用构造函数,获得对象的引用
mce.Changed += new myEventHandler(ListenerChanged); //为其事件添加自定义的处理方法
}
private void ListenerChanged(object s,EventArgs e) //声明一个符合事件委托签名的处理方法
{
Console.WriteLine("已经触发事件!");
}
public void detach()
{
mce.Changed -= new myEventHandler(ListenerChanged);
}
}
}