風子的咖啡屋

           

          2006年3月21日

          多態

            什么叫多態?我們先來談談繼承。在面向對象的編程中,繼承是一種常用的技術。假設有一個類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)編輯 收藏

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 杭州市| 六盘水市| 乌海市| 宁安市| 永宁县| 集贤县| 奇台县| 天全县| 手机| 西和县| 年辖:市辖区| 砀山县| 勐海县| 永善县| 东莞市| 曲沃县| 德阳市| 临泽县| 永吉县| 石河子市| 平阴县| 安仁县| 美姑县| 和静县| 嵊泗县| 浏阳市| 双牌县| 涪陵区| 上林县| 武平县| 洮南市| 涞水县| 顺平县| 策勒县| 红河县| 上思县| 南康市| 清涧县| 平南县| 乌审旗| 佛冈县|