面试题:晚上猫大叫一声,主人被惊醒,老鼠被下跑。用C#实现这个过程。 这个题目中一共有三个对象:猫、主人和老鼠。这三个对象之间即不属于Is a...的关系,也不属于Has a...的关系,但三者又有相互联系。 不能把主人和老鼠作为猫的成员变量出现,因为猫对象并不拥有主人和老鼠这两个对象。 不能在猫任何方法中实例化主人和老鼠。因为猫的任何动作都不会动态产生主人和老鼠。 不能在猫的Cry方法中传入主人对象和老鼠对象,因为猫大叫不是为了叫醒主人或吓跑老鼠,可能是猫正在说梦话。所以把主人和老鼠对象传递给猫的Cry()方法也不合情理。 通过上面分析我们看到,即不能把主人和老鼠作为猫的成员变量,又不能动态产生或接收主人、老鼠对象,那这三者之间如何建立关系呢?
当然是是我们刚讲过的事件。 主人类中有一个“惊醒”的方法;猫的类中有一个“大叫”的方法;老鼠类中有一个“逃跑”方法。并且猫中还有一个“大叫”事件,这个事件是多播代理,它依次调用主人的“惊醒”方法和老鼠的“逃跑”方法。
下面是具体代码: using System; //定义猫大叫事件的代理 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(Alert); } //猫大叫事件执行的处理程序 public void 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(); } }