java设计原则之里氏替换原则

What java

  Liskov Substitution Principle(LSP),任何父类出现的地方,子类必定能够出现。ide

  Whycode

  LSP是OCP原则的规范。OCP原则的关键的是抽象,而继承关系又是抽象的一种具体表现。继承

  Howip

  当子类不能完整的实现父类父类的方法,那么建议断开父子关系,采用依赖,聚合,组合等关系替代继承。下面是一个经典例子,鸵鸟不是鸟ci

  抽象鸟类,这里咱们认为鸟类都会飞,抽象方法是获取飞行速度string

abstract class Bird : IFLy
    {
        Wing[] wings;
        public Bird()
        {
            wings = new Wing[2];
        }

        protected abstract double GetFlightSpeed();

        //飞行一段距离所需时间
        public double Fly(double distance)
        {
            return distance / GetFlightSpeed();
        }
    }

燕子类,飞行速度是120it

class Swallow : Bird
    {
        protected override double GetFlightSpeed()
        {
            return 120d;
        }
    }

鸵鸟类,鸵鸟不会飞,那么飞行速度是0io

class Ostrich : Bird
    {
        protected override double GetFlightSpeed()
        {
            return 0d;
        }
    }

客户端调用class

class Program
    {
        static void Main(string[] args)
        {
            Bird bird = new Swallow();
            Double distance = 100;
            string time = bird.Fly(distance).ToString();
            Console.WriteLine(time);
            Console.ReadLine();
        }
    }

这样看是没有问题的,可是当换成下列这样的状况

class Program
    {
        static void Main(string[] args)
        {
            Bird bird = new Ostrich();
            Double distance = 100;
            string time = bird.Fly(distance).ToString();
            Console.WriteLine(time);
            Console.ReadLine();
        }
    }

这样就是违反了LSP,由于鸵鸟并不能实现全部的鸟类功能,由于它不会飞,因此没有飞行速度,那么未来客户端调用的使用,当成一种鸟类飞行,就会形成不可预知的错误。

  为何会形成这样的状况,实际上是由于抽象封装的时候出现了问题,从生态学上来讲有翅膀、有羽毛等特色的就是鸟,那么会飞的鸟应该是鸟类的一个分支,因此咱们应该从新划分类的职责范围

abstract class Bird
    {
        Wing[] wings;
        public Bird()
        {
            wings = new Wing[2];
        }
    }
abstract class FlyBird : Bird, IFLy
    {
        protected abstract double GetFlightSpeed();

        public double Fly(double distance)
        {
            return distance / GetFlightSpeed();
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            IFLy flyBird = new Swallow();
            Double distance = 100;
            string time = flyBird.Fly(distance).ToString();
            Console.WriteLine(time);
            Console.ReadLine();
        }
    }
相关文章
相关标签/搜索