您的位置:首页 > 编程语言 > Java开发

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

2016-11-20 00:00 155 查看
What

  Liskov Substitution Principle(LSP),任何父类出现的地方,子类一定可以出现。

  Why

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

  How

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

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

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

protected abstract double GetFlightSpeed();

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

燕子类,飞行速度是120

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

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

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

客户端调用

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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 java Java EE