主目錄:一個面向對象設計(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]: 前置條件和後置條件是什麼?