在Delphi中,“接口”有两种不同的含义。在OOP行话中,可以将接口看作是一个没有实现的类。在Delphi单元定义中,接口部分用于声明单元中出现的任何公共代码部分。本文将从OOP的角度解释接口。
如果您能够以代码可维护、可重用和灵活的方式创建一个坚如磐石的应用程序,那么Delphi的OOP特性将帮助您完成前70%的任务。定义接口并实现它们将有助于剩下的30%。
您可以将接口视为一个抽象类,去掉所有实现,删除所有非公共的内容。Delphi中的抽象类是一个不能实例化的类。您不能从标记为抽象的类创建对象。
让我们来看一个示例接口声明:
type IConfigChanged = interface['{0D57624C-CDDE-458B-A36C-436AE465B477}'] procedure ApplyConfigChange; end;IConfigChanged是一个接口。接口的定义很像类,使用关键字“接口”而不是“类”。编译器使用接口关键字后面的Guid值来唯一标识接口。要生成新的GUID值,只需在DelphiIDE中按Ctrl+Shift+G。您定义的每个接口都需要一个唯一的Guid值。
OOP中的接口定义了一个抽象——一个实际类的模板,该类将实现该接口,该接口将实现该接口定义的方法。接口实际上不做任何事情,它只有一个与其他(实现)类或接口交互的签名。
方法(函数、过程和属性Get/Set方法)的实现在实现接口的类中完成。在接口定义中,没有范围部分(private、public、published等),所有内容都是公共的。接口类型可以定义函数、过程(最终将成为实现接口的类的方法)和属性。当接口定义属性时,它必须定义get/set方法-接口不能定义变量。
与类一样,接口可以从其他接口继承。
type IConfigChangedMore = interface(IConfigChanged) procedure ApplyMoreChanges; end;大多数Delphi开发人员一想到接口,就会想到COM编程。然而,接口只是该语言的一个OOP特性,它们并没有专门绑定到COM。接口可以在Delphi应用程序中定义和实现,而无需接触COM。
要实现接口,需要将接口的名称添加到class语句中,如中所示:
type TMainForm = class(TForm, IConfigChanged) public procedure ApplyConfigChange; end;在上面的代码中,名为“MainForm”的Delphi表单实现IConfigChanged接口。
Warning: when a class implements an interface it must implement all its methods and properties. If you fail/forget to implement a method (for example: ApplyConfigChange) a compile time error "E2003 Undeclared identifier: 'ApplyConfigChange'" will occur. Warning: if you try to specify the interface without the GUID value you will receive: "E2086 Type 'IConfigChanged' is not yet completely defined".考虑MDI应用程序,其中可以同时向用户显示多个表单。当用户更改应用程序配置时,大多数表单都需要更新其显示、显示/隐藏某些按钮、更新标签标题等。您需要一种简单的方法来通知所有打开的表单应用程序配置已发生更改。这项工作的理想工具是界面。
配置更改时需要更新的每个表单都将实现IConfigChanged。由于中的配置屏幕以模式显示,因此当其关闭时,下一个代码确保通知所有IConfigChanged实现表单,并调用ApplyConfigChange:
procedure DoConfigChange() ; var cnt : integer; icc : IConfigChanged; begin for cnt := 0 to -1 + Screen.FormCount do begin if Supports(Screen.Forms[cnt], IConfigChanged, icc) then icc.ApplyConfigChange; end; end;Supports函数(在Sysutils.pas中定义)指示给定对象或接口是否支持指定接口。代码在Screen.Forms集合(TScreen对象的)中迭代—应用程序中当前显示的所有表单。如果表单Screen.Forms[cnt]支持该接口,则supports将返回最后一个参数的接口并返回true。
因此,如果表单实现IConfigChanged,则可以使用icc变量调用表单实现的接口方法。当然,请注意,每个表单都可以有自己不同的ApplyConfigChange过程实现。
在Delphi中定义的任何类都需要有一个祖先。TObject是所有对象和组件的最终祖先。上述思想也适用于接口,IInterface是所有接口的基类。IInterface定义了3种方法:QueryInterface、\u AddRef和\u Release。
这意味着我们的IConfigChanged也有这3种方法,但我们还没有实现它们。这是因为TForm继承自已经为您实现IInterface的TComponent!当您想要在继承自TObject的类中实现接口时,请确保您的类继承自TInterfacedObject。因为TInterfacedObject是一个实现界面的ToObject。例如:
TMyClass = class(TInterfacedObject, IConfigChanged) procedure ApplyConfigChange; end;总之,IUnknown=界面。IUnknown代表COM。
...行诸如检索、更新和插入XML数据之类的操作。 作为一名Delphi程序员,您应该知道如何使用XML文档。 xml与delphi 有关将Delphi与XML配对的更多信息,请阅读: 了解如何将TTreeView组件项存储到XML(保留树节点的文本和其他属性)...
如果您计划编写可以与多个版本的Delphi编译器一起使用的Delphi代码,您需要知道您的代码是在哪个版本下编译的。 假设您正在编写自己的商业自定义组件。组件的用户可能具有与您不同的Delphi版本。如果他们试图重新编译组...
希望掌握Delphi编程语言的初学者应该已经熟悉Microsoft Windows的基础知识。学习Delphi是最容易的,如果你从一个有指导的、基于教程的参考框架来学习它。 基本概念 从一堂历史课开始,介绍(Turbo)Pascal到Delphi 2005的演变,例...
如果您打算成为一名优秀的Delphi程序员,那么“接口”、“实现”和“使用”等词需要在您的编程知识中占有特殊的位置。 德尔福项目 当我们创建一个Delphi应用程序时,我们可以从一个空白项目、一个现有项目或Delphi的一...
Delphi DBGrid是一个功能强大的组件,如果您正在开发数据感知应用程序,那么您可能每天都在使用它。下面,我们将了解如何向您的数据库应用程序中添加更多用户肯定会喜欢的功能。 按照《Delphi数据库编程初学者指南》中描...
Delphi的编程语言是强类型语言的一个例子。这意味着所有变量必须是某种类型。类型本质上是一种数据的名称。当我们声明一个变量时,我们必须指定它的类型,它决定了变量可以保存的值集以及可以对其执行的操作。 Delphi...
在Delphi为支持通过网络(internet、intranet和local)交换数据的应用程序而提供的所有组件中,最常见的两个组件是TServerSocket和TClientSocket,这两个组件都旨在通过TCP/IP连接支持读写功能。 winsock和delphi套接字组件 Windows Sockets(W...
...,以及如何处理这些错误。 以下内容包括: Excel和Delphi之间的数据传输方法。如何使用ADO(ActiveX数据对象)和Delphi连接Excel。 使用Delphi和ADO创建Excel电子表格编辑器 从Excel中检索数据。如何在Excel工作簿中引用表(或范围)...
...以暂停和重新启动,并且不显示任何用户界面。 使用delphi的服务应用程序 使用Delphi创建服务应用程序: 创建服务、安装和卸载服务应用程序、使服务执行某些操作,并使用TService.LogMessage方法调试服务应用程序。 使用Delphi...
从代码中调用函数“DoStackOverflow”一次,您将得到Delphi引发的EStackOverflow错误,并显示消息“stack overflow”。 function DoStackOverflow : integer; begin result := 1 + DoStackOverflow; end; 这个“堆栈”是什么?为什么使用上面的代码会...