unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons;type
  TIBillOperate= interface  //接口類
  ['{D59DE540-C923-430C-A030-36B615778A90}']
    procedure SetBillData;
  end;
  TBillHead = Class(TInterfacedObject,TIBillOperate)  //-實現類
    procedure SetBillData;virtual;
  end;
  TMyBillHead = class(TBillHead)  //實現繼承類
    procedure SetBillData;override;
  end;
type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    procedure BitBtn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    aa: TBillHead;//對象
  public
    procedure SetBill(BillObj: TIBillOperate); //操作接口對象
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TBillHead.SetBillData;
begin
   showMessage('TBillHead');
end;
procedure  TMyBillHead.SetBillData;
begin
  showMessage('TMyBillHead');
end;procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  SetBill(aa);  //-----------------------------------第二次按Button就出錯!!
//  SetBill(TMyBillHead.Create); 改成這樣就可以了
end;procedure TForm1.FormCreate(Sender: TObject);
begin
  aa:= TMyBillHead.Create;
end;
procedure TForm1.SetBill(BillObj: TIBillOperate);
begin
  BillObj.SetBillData;
end;
end.我的意思是想在按一個button來通過SetBill(BillObj: TIBillOperate)來實現調用不同對象的SetBillData方法;但是為什麼第一次操作可以,但第二次再調用時就出錯地址錯?

解决方案 »

  1.   

    因为你用 SetBill(aa); 时,
    第一次能操作,是aa还存在。
    在第一次操作时,aa作为一个接口传入函数,
    在函数中被自动销毁,因为接口当引用数为0时就会自动销毁。
    这样的话,你的aa 就不存在了。
    所以你第二次就出错。但是你用SetBill(TMyBillHead.Create); 
    每次都有一个新的,所以不会出错。
      

  2.   

    同意楼上。补充一点,DELPHI实现了接口的类有一个隐含的约定。。
    一个对象可以不使用接口引用,但一旦一个对象使用了接口引用。。则必须维持引用。否则对象会释放。
    楼主的程序,只要第一次调用了SetBill之后。。对象就会被释放。
      

  3.   

    那如何引用從接口繼承的對象,不讓它銷毀呢?是不是隻能引用實現類對象?這樣做不是要做多個重載函數才能匹配多種實現類對象?如同
    procedure SetBill(BillObj: TBillHead1 );overload; //操作接口對象
    procedure SetBill(BillObj: TBillHead2 );overload;
    procedure SetBill(BillObj: TBillHead3 );overload;
      

  4.   

    这个其实有几种方法:
    1.你可以传递一个var 类型的 如: var BillObj: TIBillOperate2.也可以写为 const BillObj: TIBillOperate3.在创建对象的时候赋给引用
      

  5.   

    我曾試了用var billobj: TIOillOPerate.但是在SetBill(aa);調用時說aa有錯誤:實參或形參必須標識類型!types of actual or formal parameters must be identified
      

  6.   

    改成const就可以了,總算解決了。多謝樓上