里氏代換原則

        里氏代換原則講的是基類和子類的關係。只有這種關係存在是里氏代換原則才存在,不然不存在。若是兩個類A、B違反了里氏代換原則時刻從如下兩個重構方案中選擇一種:java

    (1)建立一個新的抽象類C,做爲兩個具體類的超類,將A、B共同的行爲移動到C中,從而解決兩者行爲是不一致的問題。
ide

    (2)將B到A的繼承關係改成委派關係。
this

本文例子描述的是第一種重構方法,第二種參見合成/聚合複用原則一文。
spa

正方形可不能夠被當作長方形的子類?
code

package Liskov.version1;

public class Rectangle {
	private long width;
	private long height;
	
	public long getWidth() {
		return width;
	}
	public void setWidth(long width) {
		this.width = width;
	}
	public long getHeight() {
		return height;
	}
	public void setHeight(long height) {
		this.height = height;
	}
}
package Liskov.version1;

public class Square {
	private long side;

	public long getSide() {
		return side;
	}

	public void setSide(long side) {
		this.side = side;
	}
	
}

由於此時的正方形類不是長方形類的子類,    所以不存在里氏代換關係。
對象

那若是把正方形類定義爲長方形類的子類呢,會有什麼問題?
繼承

package Liskov.version2;

import Liskov.version1.Rectangle;

public class Square extends Rectangle{
	private int side;

	public int getSide() {
		return side;
	}

	public void setSide(int side) {
		this.side = side;
	}

}
package Liskov.version2;

import Liskov.version1.Rectangle;

public class smartTest {
	public void resize(Rectangle r){
		while(r.getHeight() <= r.getWidth())
			r.setWidth(r.getWidth()+1);
	}
}

若是smartTest類傳入的是Rectangle對象,resize()方法將不斷增長,直至超過長度而聽下來;若是傳入的是Square對象時,正方形少的邊會不斷增長直至溢出。get


代碼重構,依據白馬黑馬都是馬的觀點io

package Liskov.version3;

public interface Quardrangle {
	public long getHeight();
	public long getWeight();
}
package Liskov.version3;

public class Rectangle implements Quardrangle {

	private long width;
	private long height;
	
	public long getWidth() {
		return width;
	}

	public long getHeight() {
		return height;
	}

	public void setWidth(long width) {
		this.width = width;
	}

	public void setHeight(long height) {
		this.height = height;
	}
}
package Liskov.version3;

public class Square implements Quardrangle{
	private long side;

	public long getSide() {
		return side;
	}

	public void setSide(long side) {
		this.side = side;
	}

	@Override
	public long getHeight() {
		// TODO Auto-generated method stub
		return side;
	}

	@Override
	public long getWidth() {
		// TODO Auto-generated method stub
		return side;
	}
	
}

    那麼破壞里氏代換原則的問題是怎麼避免的呢?祕密在於基類Quadrangle沒有賦值方法,所以相似於smartTest的resize()方法不可能適用於Quadrangle類型,只能適用於不一樣的具體子類Rectangle和Square,所以里氏代換原則不可能被破壞。
class

相關文章
相關標籤/搜索