从警察抓小偷看委托
前言:我的类名,方法名都是汉字,大家不要学我,因为这是不规范的。。。。。。
警察类:
1 namespace 警察抓小偷 2 { 3 class 警察 4 { 5 private string name; 6 private string color; 7 8 public 警察(string name,string color) 9 { 10 this.name = name; 11 this.color = color; 12 } 13 14 public void 警察来了(小偷 sef1,小偷 sef2) 15 { 16 Console.WriteLine(color+"的警察"+name+"来了"); 17 18 sef1.小偷快跑(); 19 sef2.小偷快跑(); 20 } 21 22 } 23 }
小偷类:
1 namespace 警察抓小偷 2 { 3 class 小偷 4 { 5 private string name; 6 private string color; 7 8 public 小偷(string name, string color) 9 { 10 this.name = name; 11 this.color = color; 12 } 13 14 public void 小偷快跑() 15 { 16 Console.WriteLine(color+"的小偷"+name+"说:警察来了,快跑,我使劲的快跑"); 17 } 18 } 19 }
控制台代码:
1 namespace 警察抓小偷 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 警察 polic = new 警察("黑猫警长","黑色"); 8 9 小偷 sef1 = new 小偷("大宝","白色"); 10 小偷 sef2 = new 小偷("小宝","蓝色"); 11 polic.警察来了(sef1,sef2); 12 Console.ReadLine(); 13 } 14 } 15 }
结果图:
很好,这功能可以实现,警察叔叔来了之后呢,小偷先生会马上逃跑。但是,大家注意到了吗?如果再来一个小偷先生“三宝”怎么办呢?是不是要在警察类的警察来了方法中再添加一个参数然后方法体里面再调用一次,如果大家认为这没什么的话我只能说:你真可爱。
现在来说说这个方法的缺点:扩展性特别差,多来几个小偷的话就要在警察类改来改去的直到你焦头烂额。那么怎么改进呢?用委托。
小偷类就不需要改了,咱们来看警察类:
1 namespace 警察抓小偷 2 { 3 class 警察 4 { 5 private string name; 6 private string color; 7 8 public 警察(string name,string color) 9 { 10 this.name = name; 11 this.color = color; 12 } 13 14 public void 警察来了() 15 { 16 Console.WriteLine(color+"的警察"+name+"来了"); 17 if (vae!=null) 18 { 19 vae(); 20 } 21 22 } 23 public Action vae; 24 } 25 }
再来看看控制台代码:
1 namespace 警察抓小偷 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 警察 polic = new 警察("黑猫警长","黑色"); 8 9 小偷 sef1 = new 小偷("大宝","白色"); 10 小偷 sef2 = new 小偷("小宝","蓝色"); 11 polic.vae += sef1.小偷快跑; 12 polic.vae += sef2.小偷快跑; 13 polic.警察来了(); 14 Console.ReadLine(); 15 } 16 } 17 }
结果图就不看了吧,和上面的是一样的。
使用这个委托相对于上面的方法有什么好处呢?
第一:我的警察类只要写完就可以不动它了,就让它安安静静的做个美男子吧。
第二:小偷先生什么时候加入了新成员,我只需要在控制台里面把这个新成员加到委托机制里面就好。
--------------------------------------------------------我是帅气的分割线----------------------------------------------------------
也许有人会说了,用委托之后呢控制台的代码里面还是要写polic.vae += sef1.小偷快跑; 这样之类的代码,也很多呀。而且你在控制台输入 polic.vae(); 也可以出来小偷先生们的反应,那你写 警察来了这个方法是干嘛。 嗯嗯,看到这点的同学说明你思考了,下面我们来用 事件Event 来对上面的委托代码进行一些优化。event有一个发布订阅机制,我们来看看是怎么运行的。
警察类:
1 namespace 警察抓小偷 2 { 3 class 警察 4 { 5 private string name; 6 private string color; 7 8 public 警察(string name,string color) 9 { 10 this.name = name; 11 this.color = color; 12 } 13 14 public void 警察来了() 15 { 16 Console.WriteLine(color+"的警察"+name+"来了"); 17 if (vae!=null) 18 { 19 vae(); 20 } 21 22 } 23 public event Action vae;//Look!这里是事件的发布 24 } 25 }
小偷类:
1 namespace 警察抓小偷 2 { 3 class 小偷 4 { 5 private string name; 6 private string color; 7 8 public 小偷(string name, string color,警察 police) //多加了一个参数 9 { 10 this.name = name; 11 this.color = color; 12 police.vae += this.小偷快跑; //这里就是事件的订阅机制 13 } 14 15 public void 小偷快跑() 16 { 17 Console.WriteLine(color+"的小偷"+name+"说:警察来了,快跑,我使劲的快跑"); 18 } 19 } 20 }
控制台:
1 namespace 警察抓小偷 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 警察 polic = new 警察("黑猫警长","黑色"); 8 9 小偷 sef1 = new 小偷("大宝","白色",polic); 10 小偷 sef2 = new 小偷("小宝","蓝色",polic); 11 //polic.vae += sef1.小偷快跑; 这个已经不需要打了,哈哈哈 12 //polic.vae += sef2.小偷快跑; 这个已经不需要打了,哈哈哈 13 polic.警察来了(); 14 //polic.vae(); 这段代码你也打不出来了,因为事件只能在本类使用,外部是无法调用的。 (可以+=,把方法注册进去,上面的两段注释代码就是+=) 15 Console.ReadLine(); 16 } 17 } 18 }
通过事件的发布订阅机制是不是感觉这代码又简洁了不少呢,下面我们来简单的介绍一下事件。
事件是一种特殊的委托,或者说是一种受限制的委托(因为事件只能在本类使用,外部无法调用(可以+=注册进新方法))
一般来说,委托常用来表示回调,事件常用来表达外发的接口。更多内容大家自己去百度。