隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
          數據加載中……

          在delphi中如何動態建立類的實例

          本文為原創,如需轉載,請注明作者和出處,謝謝!


              在面向對象語言中,用兩種方法建立類的實例:靜態建立和動態建立。靜態建立就是在程序中顯式地建立類的實例,如c1 = TClass1.Create()。而動態建立是在只知道類名的前題下建立類的實例。動態建立在實現上要比靜態建立更靈活,因為動態建立無需引用被建立 類,并且更容易實現如多態等面向對象特性。

          一、    動態建立類的實例
          在delphi中動態建立類的實例可分為4步。
          1. 聲明一個從TPersistent繼承的類。因為在注冊類時要求必須從TPersistent繼承。
          2. 注冊類。可以使用RegisterClass等過程進行注冊。
          3. 驗證類是否被注冊(可選)。如果確定要建立的類已經注冊了,可以省略此步。
          4. 得到并建立類。可使用FindClass(classname)得到要建立的類,然后使用Create方法建立類的實例。
          下面給出一個動態建立類實例的簡單實現。
          第一步的代碼
          TClass1 = class(TPersistent)
          public
            function GetValue(): String;
          end;

          function TClass1.GetValue(): string;
          begin
            result := 'hello world';
          end;
          第二步的代碼
          Initialization //可將這兩行放在end.的前面
            RegisterClass(TClass1);
          第三步和第四步的代碼
          procedure TForm1.Button1Click(Sender: TObject);
          var
            class1: TClass1;
          begin
            if GetClass('TClass1')<>nil then
            begin
              class1 := FindClass('TClass1').Create as TClass1;
              showmessage(class1.GetValue);
            end;
          end;

          在delphi 中不僅可以根據類名動態建立類的實例,而且在注冊時可以給類起一個別名,在建立類的實例時即可以使用類名,也可以使用別名。如上述代碼中 RegisterClass(TClass1);可改為RegisterClassAlias(TClass1, ‘class1’);。而FindClass(‘TClass1’)也可改為FindClass(‘class1’)。另外,如果注冊的類比較多,也可使 用RegisterClasses一次注冊多個類。RegisterClasses的定義如下。
          procedure RegisterClasses(AClasses: array of TPersistentClass);
          首先聲明一個TpersistentClass類型的數組,然后將要注冊的類按順序賦到這個數組中,最后調用RegisterClasses即可。

          二、通過動態建立實現多態
          多 態在程序設計中是非常重要的概念之一。它主要是通過繼承來實現的。簡單地說,就是n個類從一個類繼承或實現一個接口,這n個類繼承父類的所有 virtual方法或實現父接口的所有方法,并做出不同的實現。這n個類的實現都不一樣,而它們的調用確是一樣的,即對于調用來說是透明的。
          如果使用靜態建立類實例的方法實現多態,當類很多時需要進行大量的判斷。而使用動態建立類實例的方法只要將子類的類名或別名當做參數傳入即可。下面舉一個例子如何在delphi中利用動態建立類實例的方法實現多態。
            //定義父類
          TClassParent = class(TPersistent)
            public
          //這是一個抽象虛函數,相當于c++的純虛函數
          function Greet(name: string): string; virtual; abstract; 
          end;
          //定義兩個子類
            TEnglish = class(TClassParent)
              function Greet(name: string): string; override;
            end;
            TChinese = class(TClassParent)
              function Greet(name: string): string; override;
            end;

            //實現兩個子類的Greet函數
          { TClassEnglish }
          function TEnglish.Greet(name: string): string;
          begin
            result := 'hello ' + name;  //返回英文的問候
          end;
          { TClassChinese }
          function TChinese.Greet(name: string): string;
          begin
            result := '您好 ' + name;  //返回中文的問候
          end;

          //注冊兩個子類
          initialization
            RegisterClassAlias(TEnglish, 'eng');
            RegisterClassAlias(TChinese, 'chn');

          //根據用戶的選擇建立類的實例
          procedure TForm1.Button2Click(Sender: TObject);
          var
            parent: TClassParent;
          begin   
            if GetClass(combobox1.Items[combobox1.itemindex])<>nil then
            begin
          //此處FindClass的參數可以是類名,也可以是別名
          //本例中將類名放入了combobox中
              parent :=  FindClass(combobox1.Items[combobox1.itemindex]).Create as TClassParent;
              showmessage(parent.Greet('bill gates'));
            end;
          end;
           
          程序界面






          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2008-05-10 19:10 銀河使者 閱讀(3196) 評論(0)  編輯  收藏 所屬分類: delphi 原創

          主站蜘蛛池模板: 伊宁县| 烟台市| 梁河县| 汾西县| 天峨县| 淄博市| 金塔县| 兰考县| 巩留县| 丰台区| 庐江县| 泉州市| 武夷山市| 福泉市| 丘北县| 临漳县| 江达县| 理塘县| 洛阳市| 昌平区| 堆龙德庆县| 固始县| 洪泽县| 威信县| 广丰县| 迁西县| 镇远县| 汪清县| 禄丰县| 安新县| 海宁市| 凤庆县| 宁蒗| 平阳县| 浏阳市| 合水县| 基隆市| 都昌县| 常熟市| 鹤岗市| 辽阳市|