設計模式-裡氏替換原則
優點
面向對象的語言繼承必不可少的,有如下優點
- 代碼共享,減少建立類的工作量
- 提高代碼的重用性
- 提高代碼的可擴充性
- 提高産品代碼的開放性
- 繼承侵入性 隻要繼承,必須擁有父類的内容
- 降低代碼的靈活性,子類必須擁有父類的屬性和方法
- 增強耦合性。
提供規範
裡氏替換原則,為繼承定義規範。
長方形是不是正方形
正方形是一種特殊的長方形,如果将正方形設計為長方形的子類,不符合裡氏替換原則
下方有三個類
類圖如下

關系如上所示
package demo1;
public class SmartTest {
/*
* 長方形的長增加超過寬
*
* @param r
* */
public void resize(Rectangle r) {
while (r.getHeight() <= r.getWidth()) {
r.setHeight(r.getHeight() + 1);
}
}
}
package demo1;
/*
* 定義一個長方形類
* @author ming
* */
public class Rectangle {
protected long width; // 可以通路基類繼承而來的,不能通路基類本身的,對同包内的可見,并且子類也可見
protected long height;
public void setWidth(long width) {
this.width = width;
}
public long getWidth() {
return this.width;
}
public void setHeight(long height) {
this.height = height;
}
public long getHeight() {
return this.height;
}
}
package demo1;
/*
* 定義一個正方形類繼承自長方形類
*
* @author ming
*
* */
public class Square extends Rectangle{
public void setWidth(long width, long height) {
this.width = width;
this.height = height;
}
public long getWidth() {
return width;
}
public void setHeight(long height, long width) {
this.height = height;
this.width = width;
}
public long getHeight() {
return height;
}
}
在上面的三塊代碼中,當調用SmartTest類的resize方法的時候,如果傳入的是父類,那麼将會可以的,如果傳入的是子類,正方形,那麼将會不可以的。
即。上方的為長方形行,正方形不行。
是以上面的栗子不符合裡氏替換原則。
解決方法,使用繼承時,要遵守裡氏替換原則,類B繼承類A時,不要重寫父類A的方法,也不能重載父類A的方法。
如果代碼更改如下更改
讓其兩個都共同定義同一個父類即可
其中最上層的類為兩個類的抽象類。
改進如下
package com.ming;
/*
* 定義一個四邊形類,隻有get方法set方法
* @author ming
* */
public abstract class Quadrangle {
protected abstract long getWidth();
protected abstract long getHeight();
}
package com.ming;
public class Rectangle extends Quadrangle {
private long width;
private long height;
public void setWidth(long width) {
this.width = width;
}
public long getWidth() {
return this.width;
}
public void setHeight(long height) {
this.height = height;
}
public long getHeight() {
return this.height;
}
}
package com.ming;
public class Square extends Quadrangle{
private long width;
private long height;
public void setWidth(long width) {
this.height = width;
this.width = width;
}
public long getWidth() {
return this.,width;
}
public void setHeight(long height) {
this.height = height;
this.width = height;
}
public long getHeight() {
return this.height;
}
}
在上方的圖中,由于兩個為平級關系,是以父類的地方,換成子類也都可以。
總結
裡氏替換原則;父類可以的地方,換成子類也同樣可以。
為什麼要符合
一個栗子
package com.ming2;
public class A {
public int func1(int a, int b) {
return a-b;
}
}
package com.ming2;
public class B extends A{
public int func1(int a, int b) {
return a+b;
}
public int func2(int a, int b) {
return func1(a,b)+100; // 調用func1
}
}
在上方中,如果這樣書寫
package com.ming2;
public class Client {
public static void main(String[] args) {
B b = new B();
System.out.println(b.func1(100, 50));
}
}
就違反了裡氏替換原則,即子類能使用的時候,父類也必須能使用。
www.iming.info