本文假定讀者已經了解有關正方形不是長方形的相關內容。
之前人們討論的正方形長方形的問題的關鍵在哪里?我覺得就在于改動長方形的邊的長度。我們可以這么考慮一下,一個長方形的instance的邊長應該是可變的嗎?我覺得一旦一個長方形的邊長改變之后它就成了另一個長方形了(一個新的instance)。所以長方形類里面不應該有改變其邊長的方法,一個長方形實例各個的邊長應當在new它的時候確定下來,并且它們應當是immutable的。基于這種考慮,我設計的長方形和正方形的類如下所示:
//長方形
public class Rectangle {
private final int width;
private final int height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int getArea() {
return width*height;
}
}
//正方形
public class Square extends Rectangle{
private final int side;
public Square(int side) {
super(side, side);
this.side = side;
}
public int getSide() {
return side;
}
}
這種繼承關系就既符合現實中的父子關系也遵循LSP。之所以這么設計,我的想法是一個類所具有的方法不應當能夠改變其本質。比如有一個Men類,它可以有eat(),sleep(),work(),makeLovewith(Person p)方法,但是如果你在里面定義denatureToWomen(),denatureToEunuch()就很不恰當了,因為這改變了其本質,導致這個Men的實例不再屬于Men類(至少已經和現實不吻合)了。除非這兩個方法不能改變該實例本質,否則在Men里面定義這兩個方法本身就是有問題的。不過如果用下面這種方式定義也許可行:
public Women denatureToWomen() {
Women w = new Women();
//set attributes here
return w;
}
public Eunuch denatureToEunuch() {
Eunuch e = new Eunuch();
//set attributes here
return e;
}
這樣一來,調用denatureToWomen()會產生一個新的實例,原來的那個Men實例依然存在,這和現實生活依然不吻合,現實生活中一個實例不光可以上型(upcast),還可以平行型,寒。。。
總之一句話,一個類的方法不應該改變其實例的本質。
posted on 2007-09-20 16:33
teasp 閱讀(2728)
評論(13) 編輯 收藏 所屬分類:
Java學習