里氏替换原则(Liskov Substitution Principle)
在面向对象的程序设计中,里氏替换原则(Liskov Substitution principle)是对子类型的特别定义。它由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次会议上名为“数据的抽象与层次”的演说中首先提出。里氏替换原则的内容可以描述为: “派生类(子类)对象可以在程式中代替其基类(超类)对象。”,所有引用基类的地方必须能透明化地使用其子类的对象。多态是一种面向对象的机制(面向对象三大特性之一),它包括静态多态(函数重载)和动态多态(函数覆盖,或者成为动态绑定),通常是指动态多态,即程序在运行时,子类对象的行为(方法)可以覆盖父类对象的行为(方法)。而里氏代换原则(LSP)是一种面向对象设计原则,任何使用父类的地方都可以使用子类对象,使得我们可以针对父类编程,而运行时再确定使用哪个子类对象,从而提高系统的可扩展性和可维护性。在里氏代换原则中,实际上也使用了多态机制,子类对象在覆盖父类对象时,通过多态即可覆盖父类的行为。 子类必须完全实现父类有的方法,如果子类没有父类的某项内容,就断掉继承;子类可以有父类没有的东西,所以子类的出现的地方,不一定能用父类来代替;透明,就是安全,父类的东西换成子类后不影响程序。
例如,
1)反面示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication { class Program { static void Main(string[] args) { { Animal animal = new AnimalBird("鸟"); animal.Eat(); animal.Move(); animal.Fly(); } { Animal animal = new AnimalCow("牛"); animal.Eat(); animal.Move(); animal.Fly();//牛能飞这样的设计,继承了不应该用的方法,违背里氏替换原则 } Console.ReadKey(); } } public class Animal { protected string _Name = null; public Animal(string name) { this._Name = name; } public void Eat() { Console.WriteLine($"{this._Name} 吃东西"); } public void Move() { Console.WriteLine($"{this._Name} 走路"); } public void Fly() { Console.WriteLine($"{this._Name} 起飞"); } } public class AnimalCow : Animal { public AnimalCow(string name) : base(name) { } } public class AnimalBird : Animal { public AnimalBird(string name) : base(name) { } } }
2)里氏替换原则
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication { class Program { static void Main(string[] args) { { Animal animal = new Bird("鸟"); animal.Eat(); animal.Move(); animal.Fly(); } { Animal animal = new Cow("牛"); animal.Eat(); animal.Move(); //animal.Fly(); } Console.ReadKey(); } } public class Animal { protected string _Name = null; public Animal(string name) { this._Name = name; } public void Eat() { Console.WriteLine($"{this._Name} 吃东西"); } public void Move() { Console.WriteLine($"{this._Name} 走路"); } } public class Bird : Animal { public Bird(string name) : base(name) { } public void Fly() { Console.WriteLine($"{this._Name} 起飞"); } } /* //其它鸟可以这样继承 public class Peacock : Bird { public Cow(string name) : base(name) { } } */ public class Cow : Animal { public Cow(string name) : base(name) { } } public class Bird : Animal { public Bird(string name) : base(name) { } } }