全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:5316
推到 Plurk!
推到 Facebook!

請問一下Delphi的interface的用法

缺席
aAlan
一般會員


發表:38
回覆:24
積分:12
註冊:2004-07-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-01-13 22:40:58 IP:140.122.xxx.xxx 未訂閱
以下程式碼, 1.紅色的部分這樣寫是什麼意思呢? 2.粗體部分實在不懂為何等號兩邊的型態不同,卻可以做assign的動作?    program myProject;    uses SysUtils,  Dialogs;    type   IMyInterface = interface     procedure P1;     procedure P2;   end;      TMyImplClass = class     procedure P1;     procedure P2;   end;      TMyClass = class(TInterfacedObject, IMyInterface) FMyImplClass: TMyImplClass; property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface; end; procedure TMyImplClass.P1; begin ShowMessage('目前是執行P1函數'); end; procedure TMyImplClass.P2; begin ShowMessage('目前是執行P2函數'); end; var MyClass: TMyClass; MyInterface: IMyInterface; begin MyClass := TMyClass.Create; MyClass.FMyImplClass := TMyImplClass.Create; MyInterface := MyClass; MyInterface.P1; // calls TMyClass.MyP1; MyInterface.P2; // calls TImplClass.P2; end.
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-01-14 11:23:00 IP:218.18.xxx.xxx 未訂閱
把你的问题简化一下,更容易理解。下面是我自己在D7里写的代码:    
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;    type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;      IMyIntf=interface
    procedure ShowMe(S:String);
  end;      TMyClass=class(TInterfacedObject,IMyIntf)
    procedure ShowMe(S:String);
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}    { TMyClass }    procedure TMyClass.ShowMe(S: String);
begin
  ShowMessage('Hello, ' S);
end;    procedure TForm1.Button1Click(Sender: TObject);
var
  myClass:TMyClass;
  MyIntf:IMyIntf;
begin
  myClass:=TMyClass.Create;
  MyIntf:=myClass;
  try
    MyIntf.ShowMe('Jack');
  finally
    MyIntf:=nil;
  end;
end;    end.    
解释一下:Interface其实就是个定义,一个class如果包含某个Interface,这个class就要“实现”这个Interface里定义的函式或过程。则在这个class的对象实例里就有:1. 这个函式或过程的具体的执行代码;2. 在对象的VMT表里有这个执行代码的POINTER。 上面的例子,先定义一个Interface,里面有一个procedure ShowMe(S:String)。 然后,TMyClass=class(TInterfacedObject,IMyIntf),定义一个新的class,它从TInterfaceObject继承下来,并且要实现IMyIntf。其实它也可以从其它的类比如TObject或者TComponent继承下来。这里采用从TInterfacedObject继承下来的原因是TInterfacedObject已经实现了IInterface的几个必须要实现的函式,新的类从它继承下来就不用再去重新写一遍代码了。 新的类的定义里既然包含了IMyIntf,就要实现这个IMyIntf里定义的过程。 然后,按照DELPHI的语法,因为这个类实现了IMyIntf,因此可以直接:MyIntf:=myClass; 这是DELPHI的语法的规定。这样写如果有点难理解,可以用另外一种写法: MyIntf:=IMyIntf(myClass); 这样写,看起来有一个强制类型转换,强制把myClass转换为IMyIntf,似乎容易理解一些? 理解接口,可以把它理解为一些函式和过程的定义。事先定义好后,不同的类都可以使用这个定义,实现这个定义里的过程。好处就是调用不同的类的相同的接口里的方法(过程),就都可以用相同的语法了。我理解,这就是所谓的“多态”? 对于不用接口,类似的做法是在基础类的定义里使用抽象的方法定义,在继承的不同的子类里实现这个抽象的方法,也可以达到相同的效果。但限制是所有不同的子类都必须是从同一个基础类继承下来。而使用接口,不同的类完全可以继承自不同的父类,只要它的定义里都包含相同的接口就可以了。 另外一个好处是,一个类实现的接口是允许同时有很多个的。比如: TMyClass=class(TMyClassBase,IMyIntf1,IMyIntf2,IMyIntf3),允许这样来定义,弹性就强多了。
aAlan
一般會員


發表:38
回覆:24
積分:12
註冊:2004-07-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-01-14 13:07:53 IP:140.122.xxx.xxx 未訂閱
由此可知在Delphi 中 1.class和interface有一些奇特的關係,根據pcplayer99 的說法是: 某一個class實作某個interace,那麼該interface 可以轉型成該class, 不過還是覺得懵懵懂懂的! 希望專家們能否再舉一些例子幫助消化瞭解呢?    2.另外在IMyInterface有宣告兩個Procedure P1及P2,而在TMYImpClass也 宣告了兩個procedure P1及P2,這是代表什麼意思呢?    3.有一行property MyImplclass:TMyImplClass read FMyImplClass Implements IMyInterface;怎麼忽然間會冒出這一行呢? 最後還是謝謝pcplayer99分享他的經驗,感謝!    
引言: 以下程式碼, 1.紅色的部分這樣寫是什麼意思呢? 2.粗體部分實在不懂為何等號兩邊的型態不同,卻可以做assign的動作? program myProject; uses SysUtils, Dialogs; type IMyInterface = interface procedure P1; procedure P2; end; TMyImplClass = class procedure P1; procedure P2; end; [red]TMyClass = class(TInterfacedObject, IMyInterface) FMyImplClass: TMyImplClass; property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface; end; procedure TMyImplClass.P1; begin ShowMessage('目前是執行P1函數'); end; procedure TMyImplClass.P2; begin ShowMessage('目前是執行P2函數'); end; var MyClass: TMyClass; MyInterface: IMyInterface; begin MyClass := TMyClass.Create; MyClass.FMyImplClass := TMyImplClass.Create; MyInterface := MyClass; MyInterface.P1; // calls TMyClass.MyP1; MyInterface.P2; // calls TImplClass.P2; end.
發表人 - aalan 於 2005/01/14 13:10:41
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-01-14 13:21:04 IP:218.18.xxx.xxx 未訂閱
引言: 由此可知在Delphi 中 1.class和interface有一些奇特的關係,根據pcplayer99 的說法是: 某一個class實作某個interace,那麼該interface 可以轉型成該class, 不過還是覺得懵懵懂懂的! 希望專家們能否再舉一些例子幫助消化瞭解呢? 2.另外在IMyInterface有宣告兩個Procedure P1及P2,而在TMYImpClass也 宣告了兩個procedure P1及P2,這是代表什麼意思呢? 3.有一行property MyImplclass:TMyImplClass read FMyImplClass Implements IMyInterface;怎麼忽然間會冒出這一行呢?
“某一個class實作某個interace,那麼該interface 可以轉型成該class,”---应该是class可以转型为interface,如果class实现了那个interface的话。 至于property MyImplclass:TMyImplClass read FMyImplClass Implements IMyInterface;你可以看DELPHI的HELP是这样说的: The implements directive allows you to delegate implementation of an interface to a property in the implementing class. For example, property MyInterface: IMyInterface read FMyInterface implements IMyInterface; declares a property called MyInterface that implements the interface IMyInterface. The implements directive must be the last specifier in the property declaration and can list more than one interface, separated by commas. The delegate property must be of a class or interface type. cannot be an array property or have an index specifier. must have a read specifier. If the property uses a read method, that method must use the default register calling convention and cannot be dynamic (though it can be virtual) or specify the message directive. Note The class you use to implement the delegated interface should derive from TAggregatedObject. Delegating to an interface-type property Delegating to a class-type property
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-01-14 13:32:00 IP:218.18.xxx.xxx 未訂閱
大家一起探讨,有助于自己的提高。我以前也不了解接口还可以做成“属性”。    这是DELPHI的另一段HELP: If the delegate property is of an interface type, that interface, or an interface from which it derives, must occur in the ancestor list of the class where the property is declared. The delegate property must return an object whose class completely implements the interface specified by the implements directive, and which does so without method resolution clauses. For example,    
type
  IMyInterface = interface
    procedure P1;
    procedure P2;
  end;
  TMyClass = class(TObject, IMyInterface)
    FMyInterface: IMyInterface;
    property MyInterface: IMyInterface read FMyInterface implements IMyInterface;
  end;
var
  MyClass: TMyClass;
  MyInterface: IMyInterface;
begin
  MyClass := TMyClass.Create;
  MyClass.FMyInterface := ...  // some object whose class implements IMyInterface      MyInterface := MyClass;
  MyInterface.P1;
end;    
从这个HELP里,我们可以知道,这里有一个“some object whose class Implements IMyInterface”的这个Object没在这个HELP里列出来。 这个HELP的大概意思是:有一个IMyInterface,有一个classB实现了这个interface,这个classB没在这里列出来。 现在有一个classA,它有个property,其类型就是这个interface. 当然,为支持这个property,它有个private的变量:FMyInterface: IMyInterface; 好了。现在把ClassB实现的这个interface指给ClassA.FMyInterface,就可以把ClassA转型为IMyInterface了! DELPHI把这种方式叫做“delegate property ”。 發表人 - pcplayer99 於 2005/01/14 13:54:04
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-01-14 13:38:31 IP:218.18.xxx.xxx 未訂閱
再查HELP,原来你的代码是来自DLEPHI的HELP,仔细把HELP看多几遍就明白它在干什么了:    If the delegate property is of a class type, that class and its ancestors are searched for methods implementing the specified interface before the enclosing class and its ancestors are searched. Thus it is possible to implement some methods in the class specified by the property, and others in the class where the property is declared. Method resolution clauses can be used in the usual way to resolve ambiguities or specify a particular method. An interface cannot be implemented by more than one class-type property. For example,    
type
  IMyInterface = interface
    procedure P1;
    procedure P2;
  end;
  TMyImplClass = class
    procedure P1;
    procedure P2;
  end;
  TMyClass = class(TInterfacedObject, IMyInterface)
    FMyImplClass: TMyImplClass;
    property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
    procedure IMyInterface.P1 = MyP1;
    procedure MyP1;      end;
procedure TMyImplClass.P1;
  ...
procedure TMyImplClass.P2;
  ...
procedure TMyClass.MyP1;
  ...
var
  MyClass: TMyClass;
  MyInterface: IMyInterface;
begin
  MyClass := TMyClass.Create;
  MyClass.FMyImplClass := TMyImplClass.Create;
  MyInterface := MyClass;
  MyInterface.P1;        // calls TMyClass.MyP1;
  MyInterface.P2;        // calls TImplClass.P2;
end;
發表人 - pcplayer99 於 2005/01/14 14:23:06
系統時間:2024-04-26 18:23:06
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!