多態
什么叫多態?我們先來談談繼承。在面向對象的編程中,繼承是一種常用的技術。假設有一個類Shap,Shap有兩個方法,即draw()和erase()。Circle也是一種特殊Shap,所以只需要使用繼承的方法,使用class CricleextendsShap語句就可以創建一個新類Circle。Circle類具有Shap類的全部特征,包括所有的方法。這里只介紹了繼承,到底這和多態有什么關系,到底什么又叫多態呢?看下面的語句:
?class Shap {
?void draw(){
??System.out.println("Shap.draw()");
?}
?void erase(){
??System.out.println("Shap.erase()");
?}
?
}
class Circle extends Shap{
?void draw(){
??System.out.println("Circle.draw()");
?}
?void erase(){
??System.out.println("Circle.erase()");
?}
}
?
class Square extends Shap{
?void draw(){
??System.out.println("Square.draw()");
?}
?void erase(){
??System.out.println("Square.erase()");
?}
}
public class Picture{
?void add(Shap s){
??s.draw();
?}
?public static void main(String[] args) {
??Picture p=new Picture();
??Shap[] e={
????new Circle(),
????new Square()
??};
??for(int i=0;i<e.length;i++)
??p.add(e[i]);
?}
?
}
注意看上面加紅色的語句,及void add(Shap s){s.draw();}這表示一個Picture類的一個方法要使用Shap類作為形式參數并調用該參數的draw()方法。我們在接下來的語句中看到,不管你的Shap類的子類是Circle還是Square,在傳遞給方法add()后,add()能自動判斷是調用Circle的draw()方法還是Square的draw()方法。JAVA這種“后期綁定”的本領就叫做多態??梢钥闯?,你不必專門為Circle類寫一個add()方法,再為Square寫一個add()方法,只需要為它們的基類寫一個方法,剩下的編譯器就能為你自動選擇你想要調用的正確的方法。如果多態僅僅是一種“向上轉型”的形式的話,我們得到的僅僅是節省了一點代碼的話,也許我們不必要給予太多的關注,那多態到底有什么其它好處呢?在上面的例子中新加一個Line類,它也繼承了Shap類,如下所示:
?class Shap {
?void draw(){
??System.out.println("Shap.draw()");
?}
?void erase(){
??System.out.println("Shap.erase()");
?}
?
}
class Circle extends Shap{
?void draw(){
??System.out.println("Circle.draw()");
?}
?void erase(){
??System.out.println("Circle.erase()");
?}
}
?
class Square extends Shap{
?void draw(){
??System.out.println("Square.draw()");
?}
?void erase(){
??System.out.println("Square.erase()");
?}
}
class?Line extends Shap{
?void draw(){
??System.out.println("Line.draw()");
?}
?void erase(){
??System.out.println("Line.erase()");
?}
}
public class Picture{
?void add(Shap s){
??s.draw();
?}
?public static void main(String[] args) {
??Picture p=new Picture();
??Shap[] e={
????new Circle(),
????new Square(),
??? new Line()
??};
??for(int i=0;i<e.length;i++)
??p.add(e[i]);
?}
?
}
可以看出add()方法根本不必要知道有新類的增加而繼續正常工作。咋看,這只不過還是節省了幾行代碼的問題,你可以為每個子類都寫一個add()方法,同樣能解決問題。有新類的加入時再為這個新類寫add()方法。這不僅僅是節省了幾行代碼,多敲幾行代碼并不會如何提高編碼的效率。這是一個思想,你根本不用關心基類今天多了一個子類,明天又多了一個子類,不用擔心的你的代碼中,對于新加入的子類能否正常的運行,因為你直接與基類的接口進行通信,避免了復雜性。換句話說,你的代碼具有很好的可擴展性,基類可以隨時根據需要進行擴展而不用擔心代碼的運行問題。
posted @ 2006-03-21 08:32 風子 閱讀(213) | 評論 (0) | 編輯 收藏