第三只眼看:里氏替换原则

  面试的时候经常会被问到一个弱智题:面向对象的三个基本特征是什么?
  这时候你完全可以以请教的口气优雅的反问一道题,看看ta对"继承"的理解(不过这驳考官面子的后果可得想清楚哦!):
  class Father
  {
  public virtual void fun()
  {
  Console.WriteLine("你好!");
  }
  }
  class Son : Father
  {
  public override void fun()
  {
  Console.WriteLine("Hello !");
  }
  }
  上面两个类是继承关系吗?谈谈你对继承的理解,并用面向对象的思想改写代码。
  好了,先卖个关子不说答案是,先来看看什么是里氏替换原则。
  里氏替换原则
  定义:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。
  通俗的定义:所有引用基类的地方必须能透明地使用其子类的对象雅思答案
  按照我的理解就是:父亲能干是事情,儿子都能干;父亲干不了的,儿子也能干;所有父亲要干的事情,都可以让儿子去干。
  (所以对于上面的问题,我的回答是:这算不上继承,因为父亲说的是汉语,但是儿子只会说英语,我们是心中有对象的人,这违背了里氏替换原则,应该将子类的override换乘new)
  第三只眼:
  再来看看一个关于 人(Person)和女人(Woman)的关系。
  abstract class Person
  {
  //也可以不加virtual,但无virtual的情况下派生类能可以被覆盖,但不可以被重写。
  //更多virtual和override的区别略…
  public virtual void DoSomething()
  {
  Console.WriteLine("制造劳动工具 !"); //这是人和动物的基本区别
  }
  }
  //***************************************************************************
  class Woman : Person
  {
  override public void DoSomething()
  {
  Console.WriteLine("生小孩 !");
  }
  }
  //***************************************************************************
  class Program
  {
  static void Main(string[] args)
  {
  Person p = new Woman(); //用子类去替换父类
  p.DoSomething();
  Woman w = new Woman();
  w.DoSomething();
  Console.ReadKey();
  }
  }
  运行结果:(人) 生小孩!
  (女人)生小孩!
  不是人人都能生小孩的,用子类替换父类后,这明显违背了常理,这也违背了里氏替换原则的"子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法"的思想。
  这时候我们可以用new去隐藏父类的方法,让person继续干person的事,把生小孩的事情留给woman:托福答案
  class Woman : Person
  {
  new public void DoSomething() //或public new void DoSomething()
  {
  Console.WriteLine("生小孩 !");
  }
  }
  在思考一个关于女孩与女人的问题:
  按照常规思维,女孩属于女人,所以女孩继承自女人。
  接着上面…
  class Girl:Woman
  {
  public void Sing()
  {
  Console.WriteLine("唱歌");
  }
  }
  女孩对女人这个类进行了扩展,但是问题就出来了,这时候女孩就有了生小孩的能力,如果女人再有个大姨妈,难道女孩也要继承?
  这时如果让女人继承自女孩好像更妥,女孩可以唱歌,而女人可以唱歌、生小孩、来个例假什么的…
  虽然这没有违背面向对象继承的任何原则,但却不适合用常规思维去定义面向对象的类。
  总结:被override重写的类最好是sealed类,即该类不能再派生子类 www.yzyxedu.com
  不要用感性的常规思维去理解面向对象的继承,对于类的定义与继承一定要准确且不违背常理。

posted on 2014-04-22 22:21  程序点滴  阅读(139)  评论(0编辑  收藏  举报

全讯网   全讯网