zoukankan      html  css  js  c++  java
  • 设计模式学习笔记二:面向对象基础六之委托与事件

    委托
        
    委托作为函数的封装,可以当作给方法的特征指定一个名称。
    事件
        事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。
    事件其实就是设计模式中观察者模式在.net中的一种实现方式。
        下面看实例来学习,实例的需求是,有一只老猫叫Tom,有两只老鼠叫Jerry和Jack,Tom只要一叫‘嘧,我是Tom!’,两只老鼠就说‘老猫来了,快跑!’。通过分析应该有Cat和Mouse类,在Main函数中执行,但Cat的Shout方法触发时,Mouse就执行Run方法,不过这里如何让Cat的Shout触发时,通知两只老鼠呢?显然老猫不会认识老鼠,也不会主动通知老鼠‘我来了,你们快跑’。所以Cat类中,是不应该关联Mouse类的。此时用委托事件的方式就是最好的处理方法了。
        委托是一种引用方法的类型。一旦委托分配了方法,委托将与该方法具有完全相同的行为。委托对象用关键词delegate来声明。而事件是说在发生其他类或对象关注的事情是时,类或对象可通过事件通知他们。事件对象用event关键词声明。
        
    public delegate void CatShoutEventHandler();

    public event CatShountEventHandler CatShout;
        上面就声明了一个委托,委托名称叫CatShoutEventHandler,而这个委托所代替的方法是无参数、无返回值的方法。然后声明了一个对外公开的public 事件CatShout,他的事件类型是委托CatShoutEventhandler。表明事件发生时,执行被委托的方法。下面看完整的实践代码:
    Cat类:
    public class Cat
        {
            
    private string name;
            
    public Cat(string name)
            {
                
    this.name = name;
            }
            
    //声明委托CatShoutEventHandler
            public delegate void CatShoutEventHandler();

            
    //声明事件CatShout,他的事件类型是委托CatShoutEventHandler
            public event CatShoutEventHandler CatShout;

            
    public void Shout()
            {
                Console.WriteLine(
    "嘧,我是{0}。",name);

                
    //表明但执行Shout()方法时,如果CatShout中有对象登记事件,则执行CatShout();
                if (CatShout != null)
                {
                    CatShout();
                }
            }
        }
    Mouse类:
    public class Mouse
        {
            
    private string name;

            
    public Mouse(string name)
            {
                
    this.name = name;
            }

            
    /// <summary>
            
    /// 逃跑的方法
            
    /// </summary>
            public void Run()
            {
                Console.WriteLine(
    "老猫来了,{0}快跑!",name);
            }
        }
    main:
           static void Main(string[] args)
            {
                
    //实例化老猫Tom以及老鼠Jerry和Jack
                Cat cat = new Cat("Tom");
                Mouse mouse1 
    = new Mouse("Jerry");
                Mouse mouse2 
    = new Mouse("Jack");

                
    //表示将Mouse的Run方法通过实例化委托Cat.CatShoutEventHandler登记到Cat的事件CatShout()当中,“+=”表示“add_CatShout”
                cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
                cat.CatShout 
    += new Cat.CatShoutEventHandler(mouse2.Run);

                cat.Shout();
                Console.Read();
            }
        说明:new Cat.CatShoutEventHandler(mouse1.Run)的含义是实例化一个委托,而委托的实例其实就是Mouse类的Run方法。而‘cat.CatShout += ’表示的就是‘cat.add_CatShout(new Cat.CatShoutEventHandler(mouse1.Run)'的意思。
        “+="就是增加委托实例对象的意思。相应的"-="就是移除委托实例的意思。"-="就是"remove_CatShout()"的含义,使用它,就等于减少一个需要触发事件是通知大对象。
        运行结果:
        

        EventArgs是包含事件数据的类的基类.换句话这个类的作用就是用来在事件触发时传递数据用的。
    新增的CatShoutEventArgs类:
    public class CatShoutEventArgs:EventArgs
        {
            
    private string name;

            
    public string Name
            {
                
    get { return name; }
                
    set { name = value; }
            }
        }

    修改后的Cat类:
    public class Cat
        {
            
    private string name;
            
    public Cat(string name)
            {
                
    this.name = name;
            }
            
    //声明委托CatShoutEventHandler,此时委托所代表的方法有两个参数,object参数和CatShoutEventArgs参数
            public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs args);

            
    //声明事件CatShout,他的事件类型是委托CatShoutEventHandler
            public event CatShoutEventHandler CatShout;

            
    public void Shout()
            {
                Console.WriteLine(
    "嘧,我是{0}。",name);

                
    //表明但执行Shout()方法时,如果CatShout中有对象登记事件,则执行CatShout();
                if (CatShout != null)
                {
                    
    //声明并实例化了一个CatShoutEventArgs,并给name属性赋值为猫的名字
                    CatShoutEventArgs e = new CatShoutEventArgs();
                    e.Name 
    = this.name;
                    
    //当事件触发时,通知所登记的对象,并将发送通知的自己以及需要的数据传递过去
                    CatShout(this, e);
                }
            }
        }

    修改后的Mouse类:
    public class Mouse
        {
            
    private string name;

            
    public Mouse(string name)
            {
                
    this.name = name;
            }

            
    /// <summary>
            
    /// 逃跑的方法
            
    /// </summary>
            public void Run(object sender,CatShoutEventArgs args)
            {
                Console.WriteLine(
    "老猫{0}来了,{1}快跑!",args.Name,name);
            }
        }

    Main不用修改,请看现在运行结果:
  • 相关阅读:
    LVS基于DR模式负载均衡的配置
    Linux源码安装mysql 5.6.12 (cmake编译)
    HOSt ip is not allowed to connect to this MySql server
    zoj 3229 Shoot the Bullet(无源汇上下界最大流)
    hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割
    poj 2391 Ombrophobic Bovines(最大流+floyd+二分)
    URAL 1430 Crime and Punishment
    hdu 2048 神、上帝以及老天爷(错排)
    hdu 3367 Pseudoforest(最大生成树)
    FOJ 1683 纪念SlingShot(矩阵快速幂)
  • 原文地址:https://www.cnblogs.com/peida/p/1212566.html
Copyright © 2011-2022 走看看