主目录:一个面向对象设计(OOD)的学习思路设计bash
引子:学习
有一只小麻雀在大平原上,飞呀飞~。飞累了,看见前方一个大鸟...
小麻雀:
大鸟兄你好,本鸟叫麻雀!请问您怎么称呼?大鸵鸟:
原来是麻雀小弟呀!本鸟叫鸵鸟!小麻雀:
鸵鸟哥耶!小弟飞的累的不行!让兄弟在您雄伟的身躯上歇歇脚么?大鸵鸟:
不行!本鸟还走累了呢!那我咋办?小麻雀:
你飞呗!难道我还拖着你不成?大鸵鸟:
前提是我要是能飞的起来呀!小麻雀:
开什么玩笑!我们都是鸟,你飞不起来?“飞”是咋们鸟类的特征,想到飞就想到咋们鸟~。ui
派生类(子类)
对象可以替换其基类(超类)
对象被使用^foot1S
的对象q1
,都存在一个类型T
的对象q2
,使得在全部对T
编写的程序P
中,用q1
替换q2
后,程序P
行为功能不变,则S
是T
的子类型。 听着有些绕,我将它画一个类图便于理解:
L:芭芭拉·利斯科夫(Barbara Liskov)
由于提出这个原则的女士姓里 S:替换(Substitution)
父类能被子类替换this
替换
如上述定义所述,子类替换父类后不会影响其行为和功能。①首先谈谈要是违反LSPspa
分析.net
如今我说天上飞着一只鸟。。。设计
子类麻雀替换父类:天上飞着一只麻雀。code
子类鸵鸟替换父类:天上飞着一只鸵鸟。对象
由上由于违反了里氏替代原则,致使整个设计存在严重逻辑错误。blog
因为违反了里氏替代原则,间接的违反了OCP原则^foot2。由于明显能够看出飞翔对于鸵鸟因该是封闭的。
②再来看一些代码(LSP的违反致使OCP的违反)
有三个类:鸟、鸵鸟、麻雀。鸵鸟和麻雀都有要去北京的方法
/**
* 鸟
*/
class Bird{
public static final int IS_OSTRICH = 1;//是鸵鸟
public static final int IS_SPARROW = 2;//是麻雀
public int isType;
public Bird(int isType) {
this.isType = isType;
}
}
/**
* 鸵鸟
*/
class Ostrich extends Bird{
public Ostrich() {
super(Bird.IS_OSTRICH);
}
public void toBeiJing(){
System.out.print("跑着去北京!");
}
}
/**
* 麻雀
*/
class Sparrow extends Bird{
public Sparrow() {
super(Bird.IS_SPARROW);
}
public void toBeiJing(){
System.out.print("飞着去北京!");
}
}
复制代码
如今有一个方法birdLetGo,统一处理去北京的行为
public void birdLetGo(Bird bird) {
if (bird.isType == Bird.IS_OSTRICH) {
Ostrich ostrich = (Ostrich) bird;
ostrich.toBeiJing();
} else if (bird.isType == Bird.IS_SPARROW) {
Sparrow sparrow = (Sparrow) bird;
sparrow.toBeiJing();
}
}
复制代码
③结论
由上面的分析能够大体的了解了遵照LSP的重要性了吧!
几个继承关系的类
//动物
public class Animal {
private String food;
public Animal(String food) {
this.food = food;
}
public String getFood() {
return food;
}
}
//鸟
class Bird extends Animal{
public Bird(String food) {
super(food);
}
}
//鸵鸟
class Ostrich extends Bird{
public Ostrich() {
super("草");
}
}
//麻雀
class Sparrow extends Bird{
public Sparrow() {
super("虫子");
}
}
复制代码
在动物园对象中调用吃的方法
class Zoo {
/**
* 吃早餐
*/
public String eatBreakfast(Animal animal) {
return animal.getFood();
}
}
复制代码
分析
Object food = new Zoo().eatBreakfast(new Animal("肉"));
复制代码
String food = new Zoo().eatBreakfast(new Ostrich());
复制代码
若是LSP有效运用,程序会具备更多的可维护性、可重用性和健壮性
LSP是使OCP成为可能的主要原则之一
正是由于子类的可替换性,才使得父类模块无须修改的状况就得以扩展
[^foot3]: 敏捷软件开发 第10章 里氏替换原则(LSP) [^foot4]: 前置条件和后置条件是什么?