精品国产亚洲一区二区三区,男女作爱在线观看免费网站,欧美的又大又长做禁片A片,97国产精品人妻无码久久久

  • 相關(guān)軟件
    >談?wù)凞elphi中的類和對象 創(chuàng)建者:webmaster 更新時(shí)間:2005-07-02 01:35

    談?wù)凞elphi中的類和對象
    1.登不了大雅之堂地理解幾個(gè)概念
       說到類和對象,我們不能不提及這樣幾個(gè)概念:類,對象,實(shí)例。就我個(gè)人覺得可
    以這樣來理解:對象指的是泛稱,自然界的任何實(shí)體都可以看成一個(gè)對象;而類則是
    以這些對象某些特征而分成的一系列的種類;實(shí)例則是特指屬于某一個(gè)類的一個(gè)對象。
    好啦,這些大道理我就不用多說了。不如來一個(gè)“背道而馳”的作法,我們用Delphi
    code 來闡述這些外國人提出的一些令我們中國人不好理解的概念吧:
    var
      ABtn:TButton;
    義ABtn是屬于TButton類的一個(gè)對象,但ABtn不能說是一個(gè)實(shí)例,因?yàn)樗€沒有
    創(chuàng)建,所以我們說這是定義了一個(gè)對象,如果說定義了一個(gè)實(shí)例,多多少少有
    些不夠確切。:)
    begin
      ABtn:=TButton.Create(Self);//創(chuàng)建一個(gè)TButton的實(shí)例
      ABtn.Caption:='對象';
      ABtn.Free;
    end;

    2.對象是一個(gè)地地道道的指針
       從物理角度來看,對象就是一段地址空間,這段地址空間的標(biāo)志就是我們定義的
    類“變量”。所以我們可以把對象看成一個(gè)類的指針。大家知道,要訪問一個(gè)指針就
    必須對指針初始化。對象的既然是一個(gè)指針,也必須對它進(jìn)行初始化。如何初始化呢?
    還是說指針的初始化吧。對于一個(gè)指針可以有以下兩種方法來進(jìn)行初始化:
    (一)直接分配
    var
      Pint:^Integer;
    begin
      new(Pint);
      Pint^:=12;
      Dispose(Pint);
    end;
    (二)指向別的已分配空間的變量
    var
      Pint:^Integer;
      i:integer;
    begin
      i:=12;
      Pint:=@i;
    end;
    有趣的是,對象這種“指針”也有兩種方法初始化
    (一)直接分配
    var
      AForm:TForm;
    begin
      AForm:=TForm.Create(Self);
      AForm.ShowModal;
      AForm.Free;
    end;
    (二)指向別的已分配空間的實(shí)例
    var
      AForm:TForm;
    begin
      AForm:=Self;
      AForm.Caption:='知道了嗎?為什么會(huì)這樣呢';
    end;
    file://這個(gè)AForm和它所指向的Form實(shí)例共用同一段地址單元,所有對AForm操作都將反應(yīng)
    file://到它所對應(yīng)的Form實(shí)例之上。
    說到這,我們就很好解釋為什么過程(函數(shù))的對象參數(shù)傳遞時(shí),象這樣這的格式:
    (一)procedure SetEdit(var Edit:TEdit);
        begin
          Edit.Text:='11';
        end;

    (二)procedure SetEdit(Edit:TEdit);
        begin
          Edit.Text:='11';
        end;
    效果是一樣的了。(一)是把一個(gè)TEdit實(shí)體作為參數(shù)引用的形式進(jìn)行參數(shù)傳遞,(二)是
    把一個(gè)TEdit的對象“指針”作為參數(shù)傳遞。


    3.類可以理解成一種特殊的數(shù)據(jù)類型
        我們知道數(shù)據(jù)類型可以進(jìn)行強(qiáng)制類型轉(zhuǎn)化,類即然可以理解成一種數(shù)據(jù)類型,那
    么它也應(yīng)該可以進(jìn)行類類型轉(zhuǎn)。比方如下代碼為一個(gè)按鈕(Button1)的單擊事件:
    (一)
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ACaption:String;
    begin
      ACaption:=TButton(Sender).Caption;//Sender從TObject轉(zhuǎn)化到TButton
      ShowMessage(Format('You clicked ''%s'' !',[ACaption]));
    end;
    在這段代碼中,Sender是一個(gè)TObject型對象,我們把它強(qiáng)制轉(zhuǎn)化為TButton類型。如你
    看得不清楚,可以參照一下我們通常的數(shù)據(jù)類型的轉(zhuǎn)化:
    (二)
    procedure TForm1.Button1Click(Sender: TObject);
    var
      S_Str:String;
      P_Str:PChar;
    begin
      S_Str:='I love China!';
      P_Str:=PChar(S_Str);
      S_Str:='';
      S_Str:=String(P_Str);
      ShowMessage(S_Str);
    end;
    但是在面對對象的程序設(shè)計(jì)過程中,強(qiáng)調(diào)的是安全性,如(一)的強(qiáng)制類型轉(zhuǎn)化存在著不
    安全性。如下的代碼,依然是寫B(tài)utton1.OnClick事件:
    (三)
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      TCanvas(Sender).Brush.Color:=clRed;
    end;
    執(zhí)行一下,就會(huì)出錯(cuò)。這樣豈不是違背了面對對象的程序設(shè)計(jì)的宗旨了嗎?沒有,即然
    是類,就應(yīng)該有類特定的類強(qiáng)制轉(zhuǎn)化方法,改(三)的方法如下:
    (四)
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      (Sender as TCanvas).Brush.Color:=clRed;
    end;//用as來轉(zhuǎn)化,as就可以把錯(cuò)誤抓住,不會(huì)影響程序的正常運(yùn)行。
    說到這我順便提一下VB吧,如果學(xué)過VB的人可能覺得其中的控件數(shù)組比較爽,尤其是在
    編寫象計(jì)算器這樣的程序時(shí)。但Delphi給我們什么呢?答案是Delphi也能快速簡潔的開
    發(fā)出這樣的程序。如是操作:在窗體上放一個(gè)Edit和十個(gè)Button,把Button.Caption分
    別設(shè)為'0','1','2',...'9',然后寫一個(gè)按鈕的OnClick事件如下:
    (五)
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Edit1.Text:=Edit1.Text+(Sender as TButton).Caption;
    end;
    把別的Button的OnClick事件都關(guān)聯(lián)到Button1Click上,運(yùn)行程序。拍拍手!這樣計(jì)算器
    程序的雛形就具備了。我們用Delphi的類類型轉(zhuǎn)化,開發(fā)出來類似VB中的控件數(shù)組功能
    的程序也是很棒的嘛!:)


    4.抽象類和它的實(shí)例
        Delphi中有一種類為抽象類,你不能天真的直接為它創(chuàng)建一個(gè)實(shí)例。如:TStrings
    類。如下代碼:
    (一)
    var
      StrLst:TStrings;
    begin
      StrLst:=TStrings.Create;
      StrLst.Add('I love Japan!');
      StrLst.Free;
    end;
    這是不對的。那如何為諸如TStrings這樣的抽象類構(gòu)造實(shí)例呢?答案是借助它的非抽
    象子類。我們知道TStrings有一個(gè)TStringList非抽象子類。我們就可以這樣作:
    (二)
    var
      StrLst:TStrings;
    begin
      StrLst:=TStringList.Create;//借助其子類的構(gòu)造器,對StrLst進(jìn)行子類化
      StrLst.Add('I love China!');
      StrLst.Free;
    end;
    (三)
    var
      StrLst:TStringList;
    begin
      StrLst:=TStringList.Create;
    file://放棄吧,不要再用抽象類,完全用它的“兒子”來你的事吧 
      StrLst.Add('I love China!');
      StrLst.Free;
    end;


    5.類是一種對數(shù)據(jù)和操作高度的封裝機(jī)制
    (一)數(shù)據(jù)封裝
    unit Unit2;


    interface
    type
      TEmployee=class
      private
        FName:String;
      public
        Constructor Create;
        function  GetName:String;
        procedure SetName(AName:String);
      end;
    implementation


    { TEmployee }


    constructor TEmployee.Create;
    begin
      FName:='BlazingFire';
    end;


    function TEmployee.GetName: String;
    begin
      Result:=FName;
    end;


    procedure TEmployee.SetName(AName: String);
    begin
      FName:=AName;
    end;


    end.
    如上代碼,我們就用了一個(gè)過程SetName和一個(gè)函數(shù)GetName對私有變量FName進(jìn)行完全的
    封裝。我們要對FName操作就只有這樣:
    uses
      unit2;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      AEmployee:TEmployee;
    begin
      AEmployee:=TEmployee.Create;
      AEmployee.SetName('Rose');//利用SetName來設(shè)置FName
      MessageBox(Handle,PChar(AEmployee.GetName),'Empoyee',0);
      file://用GetName來訪問FName
      AEmployee.Free;
    end;
    (二)操作封裝
    unit Unit2;


    interface
    type
      TDivision=Class
      public
        file://多態(tài)性讓你的程序更據(jù)有“柔韌性”
        function GetDiv(Num1,Num2:Double):Double;overload;
        function GetDiv(Num1,Num2:integer):integer;overload;
      end;
    implementation


    { Division }


    function TDivision.GetDiv(Num1, Num2: Double): Double;
    begin
      try
        Result:=Num1/Num2;
      except
        Result:=0;//提供彈形處理機(jī)制,處理除數(shù)為0情況
      end;
    end;


    function TDivision.GetDiv(Num1, Num2: integer): integer;
    begin
      try
        Result:=Num1 div Num2;
      except
        Result:=0;//提供彈形處理機(jī)制,處理除數(shù)為0情況
      end;
    end;


    end.
    如上代碼我們通過類的多態(tài)性機(jī)制把除法分別處理成整除和非整除,又通過異常處理屏
    去除數(shù)為0的情況,從而保證操作的安全性,在調(diào)用時(shí),我們就可以這樣來:
    uses
      unit2;
    {$R *.dfm}


    procedure TForm1.Button1Click(Sender: TObject);
    var
      Division:TDivision;
      IValue:integer;
      FValue:Double;
    begin
      Division:=TDivision.Create;
      IValue:=Division.GetDiv(1,2);
      FValue:=Division.GetDiv(1.0,2);
      IValue:=Division.GetDiv(1,0);
      FValue:=Division.GetDiv(1.0,0);
      Division.Free;
    end;
     
    6.類是一種代碼重用機(jī)制
        比方在5中我們想對這個(gè)類加上一個(gè)GetAdd函數(shù)來作加法運(yùn)算就可以用類的繼承。如
    下寫就可以了:
    (一)
    unit Unit2;


    interface
    type
      TDivision=Class
      public
        function GetDiv(Num1,Num2:Double):Double;overload;
        function GetDiv(Num1,Num2:integer):integer;overload;
      end;
    type
      TOperation=Class(TDivision)
      public
        function GetAdd(Num1,Num2:Double):Double;
      end;
    implementation


    { Division }


    function TDivision.GetDiv(Num1, Num2: Double): Double;
    begin
      try
        Result:=Num1/Num2;
      except
        Result:=0;
      end;
    end;


    function TDivision.GetDiv(Num1, Num2: integer): integer;
    begin
      try
        Result:=Num1 div Num2;
      except
        Result:=0;
      end;
    end;


    { TOperation }


    function TOperation.GetAdd(Num1, Num2: Double): Double;
    begin
      Result:=Num1+Num2;
    end;


    end.
    這里我們從TDivision繼承了一個(gè)子類TOperation。TOperation就可以即有TDivsion
    公有方法GetDiv,又有自己的獨(dú)特的方法GetAdd。這是類為我們提供的“魚和熊掌兼
    得”之法。不錯(cuò)吧。:)

    相關(guān)文章
    本頁查看次數(shù):