線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1178
推到 Plurk!
推到 Facebook!

父子繼承問題..

尚未結案
GDMichael
一般會員


發表:27
回覆:36
積分:12
註冊:2004-10-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-12-09 17:47:38 IP:203.185.xxx.xxx 未訂閱
TSearchForm = class(TForm); - Function GetID(); Virtual; TSearchUserForm = class(TSearchForm); 現在有這樣的condition. 我想寫一個method是pass兒子的form,然後可以create出來,或許應該這樣說...我想寫到這樣的mehtod: CreateSearchForm(SearchForm: TSearchForm); 我能夠pass不同的兒子form,我試著寫那createsearchform的method,發覺每次也只會create了父親(TSearchForm),而不是我傳入來的兒子,請問應該怎樣解決? 語言如果表達不清楚,請見諒 >_<
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-12-09 19:03:41 IP:220.130.xxx.xxx 未訂閱
procedure CreateSearchForm(SearchForm: TSearchForm);
begin
  SearchForm := TSearchUserForm.Create(Application);
end;    或    function CreateSearchForm: TSearchForm;
begin
  Result := TSearchUserForm.Create(Application);
end;      因為回傳值是TSearchForm, 所以有些存取TSearchUserForm特有的屬性(非繼承),應該先作typecast.    unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;    type
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  protected
    procedure DoClick(Sender: TObject); virtual;
  public
    constructor Create(AOwner: TComponent); override;
    function GetID: string; virtual;
  end;      TFormA = class(TForm1)
  protected
    procedure DoClick(Sender: TObject); override;
  public
    constructor Create(AOwner: TComponent); override;
    function GetID: string; override;
  end;      TFormB = class(TFormA)
  protected
    procedure DoClick(Sender: TObject); override;
  public
    constructor Create(AOwner: TComponent); override;
    function GetID: string; override;
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}    { TForm1 }    constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;      Width := 300;
  Height := 300;
  Caption := ClassName;
  Color := clRed;      with TButton.Create(Self) do
  begin
    BoundsRect := Rect(0,0,200,30);
    OnClick := DoClick;
    if Self is TFormB then
    begin
      Caption := 'Do Nothing';
      OnClick := nil;
    end
    else if Self is TFormA then Caption := 'Create a FormB'
    else Caption := 'Create a FormA';        Visible := True;
    Parent := Self;
    
  end;
end;    procedure TForm1.DoClick(Sender: TObject);
begin
  TFormA.Create(Application);
end;    function TForm1.GetID: string;
begin
  Result := 'I am Form_1';
end;    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;    { TFormA }    constructor TFormA.Create(AOwner: TComponent);
begin
  inherited;
  Color := clBlue;
  Visible := True;
end;    procedure TFormA.DoClick(Sender: TObject);
begin
  TFormB.Create(Application);
end;    function TFormA.GetID: string;
begin
  Result := 'I am Form_A';
end;    { TFormB }    constructor TFormB.Create(AOwner: TComponent);
begin
  inherited;
  Color := clNavy;
end;    procedure TFormB.DoClick(Sender: TObject);
begin
  //DoNothing;
end;    function TFormB.GetID: string;
begin
  Result := 'I am Form_B';
end;    end.    
GDMichael
一般會員


發表:27
回覆:36
積分:12
註冊:2004-10-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-12-10 10:05:40 IP:203.185.xxx.xxx 未訂閱
如果如你所說,那麼我那個createsearchform是否要寫 If Self As TSearchUserForm Do ..... If Self As TSearchCompanyForm Do .... 但如果這樣,我每次有新searchform時,就要在父的createsearchform到加上 If Self As TSearchXXXForm Do ... 那樣好像不太efficiency... 請問有更好的方法是,我pass兒子的form就可以用父親的createsearchform來create呢?
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-12-10 13:25:40 IP:220.130.xxx.xxx 未訂閱
那是由父類別的觀點來看的,好處是程式碼集中較好管理.此外你也可以在個別的子類別中去改寫不同的特性.    而你的問題應該是這這樣,通常父類別的物件指標可用來指向多個自父類別繼承的子類別的實際物件(instance)    
var
  O: 父類別;
begin
  O := 子類別A.Create();
  O.存取繼承自父類別的屬性;
  子類別A(O).存取子類別A自行新增的屬性;
  O.Free;
 
  O := 子類別B.Create();
  O.存取繼承自父類別的屬性;
  子類別B(O).存取子類別B自行新增的屬性;
  O.Free;      //主要是看你用來指向實際物件的物件指標的型態及實際產生的物件型態.
  //一般來說是這樣:
  //(1)子類別A.Create() ---> 在記憶體中產生一個子類別A的實際物件  (instance),並傳回其指標;
  //(2) O := 子類別A.Create(), 其中物件指標變數O 就是用來保留(1)的回傳值,它可以是子類別A本身型態,或其父類別的型態; 所以在存取相關屬性,在必要時必須轉換其指標形型.< >    >    < >     
        
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-12-10 13:30:17 IP:220.130.xxx.xxx 未訂閱
引言 --------------------------------------------------------------------- 請問有更好的方法是,我pass兒子的form就可以用父親的createsearchform來create呢? --------------------------------------------------------------------- 你可能要Pass 子類別的 ClassType吧!
allenchan
資深會員


發表:10
回覆:306
積分:283
註冊:2004-01-06

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-12-12 18:32:11 IP:61.62.xxx.xxx 未訂閱
我想您要的這個功能,Object Pascal 的 MetaClass 應該可以達到:
type 
  TSearchFormClass = class of TSearchForm;      TSearchForm = class(TForm);
    Button1: TButton;
    procedure Button1Click(Sender: TObject);  
  private:
    SearchForm : TSearchForm;
  public:
    procedure CreateSearchForm(AClass: TSearchFormClass);  
  end;
  
  TSearchUserForm = class(TSearchForm);
  public:
  //......
  end;    implementation    procedure TSearchForm.CreateSearchForm(AClass: TSearchFormClass);
begin
  SearchForm := AClass.Create(self);
end;    使用範例:
procedure TSearchForm.Button1Click(Sender: TObject);
begin
  CreateSearchForm(TSearchUserForm); //傳入您所要生成 Form 的型別
  SearchForm.Show;
end;
發表人 - allenchan 於 2004/12/12 18:36:03
系統時間:2024-05-21 21:59:42
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!