日期:2014-05-17  浏览次数:21097 次

猫大叫一声 主人被惊醒 老鼠被下跑 (C#经典案例面试题)

                   猫大叫一声,主人被惊醒,老鼠被下跑。用C#实现这个过程。该题目经常被C#.net面试中设计成重要面试设计题,不管是用C#实现该过程还是抽象成一个game原型,仔细想想这个场景是不是跟老板监视办公室员工玩游戏类似,老板亲自或指派某人或通过软件工具来监视员工打游戏,一端员工开始打游戏,那么老板的那个“监视器”事件被触发,老板就知晓了。

                  该实例场景中有三个对象分别为:主人对象(类),老鼠对象(类),猫对象(类)。这三个对象不同时继承同一父类(不属于 Is  a ……关系),并且他们又不是同时拥有同一子类/方法/属性(不属于Has a ……关系),且场景中又相互有联系。

                 不能把主人和老鼠作为猫的变量成员出现,因为猫并不拥有主人和老鼠两个对象;且不能在猫的任何方法中实例化老鼠和主人,因为猫任何动作都不会产生老鼠和主人。主人类中肯定有一wakeup方法,老鼠类中必须有个Run方法,那么有人肯定会想到猫类中有一个Cry方法,再仔细想想猫仅仅有个Cry方法够不够,谁来触发呢?所以猫类这时候必须拥有一个惊叫的事件来触发让人类、鼠类和猫类关联起来。好了我们分析清楚了,通过猫类的惊叫事件来触发主人的惊醒,老鼠的逃跑。

具体代码如下:

 

//定义猫大叫事件的代理
public delegate void AlertHandler();
//主人类
class Human
{
  //主人被惊醒的方法
  public void Wake()
  {
     Console.WriteLine("主人:死猫别叫");
  }
}
//老鼠类
class Mouse
{
  //老鼠被吓包的方法
  public void Run()
  {
      Console.WriteLine("老鼠:有危险,快跑!");
   }
}
//猫类
class Cat
{
   //猫大叫事件
   public event AlertHandler AlertEvent;
   public Cat()
   {
   //猫大叫时执行Cry方法
     AlertEvent +=new AlertHandler(Cry);
   }
  //猫大叫事件执行的处理程序
  publicvoid Alert()
  {
    Console.WriteLine("猫:喵...喵...");
   }
  //猫大叫的方法
  public void Cry()
  {
    //触发猫大叫的事件
   AlertEvent();
   }
}
//房子类
class House
{
  //房子里有一只老鼠、一只猫和主人
  public Mouse mouse = new Mouse();
  public Cat cat = new Cat();
  public Human human = new Human();
  //由于在一个房子里,猫大叫的事件会引发老鼠“逃跑”和主人“惊醒”
  //所以在这里把老鼠“逃跑”和主人“惊醒”两个方法挂接到猫大叫的事件上。
public House()
{
  cat.AlertEvent +=new AlertHandler(mouse.Run);
  cat.AlertEvent +=new AlertHandler(human.Wake);
}

}
//客户程序
class Program
{
static void Main(string[] args)
{
//有一间房子
House h = new House();
//猫大叫
h.cat.Cry();
}
}


5楼loogloogcom2小时前
猫的这个方法好像没有用到,为什么要定义呢?npublic void Alert()n{n Console.WriteLine("猫:喵...喵...");n}
4楼loogloogcom昨天 23:13
[quote=teaspring]楼主代码里面没有调用Cat::Alert(),应该是个笔误。更大的问题是,Cat()构造函数里更应该...[/quote]n看来,英雄所见略同呀!!咱俩思路一样。n我的那个代码,简练一些,少了一个方法Alert。
3楼teaspring昨天 17:07
楼主代码里面没有调用Cat::Alert(),应该是个笔误。更大的问题是,Cat()构造函数里更应该调用Alert()而非Cry():n public Cat()n {n //猫大叫时执行Cry方法n AlertEvent +=new AlertHandler(Alert);n }nCry() 是被外部直接调用的,没必要再加入AlertEvent 列表。nn三楼的改法也可行,就是将Alert()的逻辑直接移到Cry()里面。
2楼loogloogcom昨天 16:30
现在面向对象发展了呀,n除了要识别出“类”来,还要识别出“事件”来呀nn记得以前事件的发生,就是通过调用方法来完成的。nnC#挺牛的,听说Java也模仿C#这一特征了。
1楼loogl