Delphi 中接口实现:Implementing Interfaces

 

        

目录

一、类声明(Class Declarations)

二、方法解决说明(Method Resolution Clause)

三、更改继承实现(Changing Inherited Implementations)

四、通过委托实现接口(Implementing Interfaces by Delegation)

五、委托接口类型属性(Delegating to an Interface-Type Property)

六、委托给类类型属性(Delegating to a Class-Type Property)


        接口一经声明,必须在类中实现后才能使用。在类的声明中,在类的祖先名称之后指定了类所实现的接口。

一、类声明(Class Declarations)

此类声明的形式如下 :

type className = class (ancestorClass, interface1, ..., interfaceN)memberList
end;

例如:

typeTMemoryManager = class(TInterfacedObject, IMalloc, IErrorInfo)// ...

        声明了一个名为 TMemoryManager 的类,该类实现了 IMalloc 和 IErrorInfo 接口。当一个类实现一个接口时,它必须实现(或继承实现)接口中声明的每个方法。

以下是 System.TInterfacedObject 的声明(在 Windows 平台上,在其他平台上,声明略有不同):

typeTInterfacedObject = class(TObject, IInterface)protectedFRefCount: Integer;function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;function _AddRef: Integer; stdcall;function _Release: Integer; stdcall;publicprocedure AfterConstruction; override;procedure BeforeDestruction; override;class function NewInstance: TObject; override;property RefCount: Integer read FRefCount;end;

TInterfacedObject 实现了 IInterface 接口。因此,TInterfacedObject 声明并实现了三个 IInterface 方法中的每一个。

实现接口的类也可用作基类。(上面的第一个示例将 TMemoryManager 声明为 TInterfacedObject 的直接继承)。每个接口都继承自 IInterface,实现接口的类必须实现 QueryInterface、_AddRef 和 _Release 方法。单元 System 中的 TInterfacedObject 实现了这些方法,因此是一个方便的基类,可以从中派生出其他实现接口的类。

实现接口时,接口的每个方法都会被映射到实现类中的一个方法上,该方法具有相同的结果类型、相同的调用约定、相同的参数数以及每个位置上相同类型的参数。默认情况下,每个接口方法都会映射到实现类中的同名方法。
 

二、方法解决说明(Method Resolution Clause)

通过在类声明中包含方法解析子句,可以覆盖默认的基于名称的映射。当一个类实现了两个或多个具有相同命名方法的接口时,可以使用方法解析子句来解决命名冲突。

方法解析子句的形式如下 :

procedure interface.interfaceMethod = implementingMethod;

或者

function interface.interfaceMethod = implementingMethod;

其中,implementingMethod 是该类或其祖先类中声明的方法。implementingMethod 可以是类声明中稍后声明的方法,但不能是其他模块中声明的祖先类的私有方法。

例如 :

typeTMemoryManager = class(TInterfacedObject, IMalloc, IErrorInfo)function IMalloc.Alloc = Allocate;procedure IMalloc.Free = Deallocate;// ...end;

将 IMalloc 的 Alloc 和 Free 方法映射到 TMemoryManager 的 Allocate 和 Deallocate 方法上。

方法解析子句不能改变父类引入的映射。

三、更改继承实现(Changing Inherited Implementations)

子类可以通过覆盖实现方法来改变特定接口方法的实现方式。这要求实现方法是虚拟的或动态的。

类还可以重新实现从祖先类继承的整个接口。这需要在子类的声明中重新列出接口。例如:

 

typeIWindow = interface['{00000115-0000-0000-C000-000000000146}']procedure Draw;// ...end;TWindow = class(TInterfacedObject, IWindow)// TWindow implements IWindow pocedure Draw;// ...end;TFrameWindow = class(TWindow, IWindow)// TFrameWindow reimplements IWindow procedure Draw;// ...end;

        重新实现接口会隐藏同一接口的继承实现。因此,父类中的方法解析条款对重新实现的接口没有任何影响。

四、通过委托实现接口(Implementing Interfaces by Delegation)

implements 指令允许将接口的实现委托给实现类中的一个属性。例如 :

property MyInterface: IMyInterface read FMyInterface implements IMyInterface;

声明了一个名为 MyInterface 的属性,该属性实现了接口 IMyInterface。

implements 指令必须是属性声明中的最后一个指定符,并且可以列出多个接口,中间用逗号隔开。委托属性 :

  • 必须是类或接口类型。
  • 不能是数组属性,也不能有索引说明符。
  • 必须有读取说明符。如果属性使用读取方法,则该方法必须使用默认寄存器调用约定,不能是动态的(尽管可以是虚拟的),也不能指定消息指令。

用于实现委托接口的类应该派生自 System.TAggregatedObject。

五、委托接口类型属性(Delegating to an Interface-Type Property)

如果委托属性属于接口类型,则该接口或其派生接口必须出现在声明该属性的类的祖先列表中。委托属性必须返回一个对象,该对象的类完全实现了 implements 指令指定的接口,并且不含方法解析子句。例如 :

typeIMyInterface = interfaceprocedure P1;procedure P2;end;TMyClass = class(TObject, IMyInterface)FMyInterface: IMyInterface;property MyInterface: IMyInterface read FMyInterface implements IMyInterface;end;
varMyClass: TMyClass;MyInterface: IMyInterface;
beginMyClass := TMyClass.Create;MyClass.FMyInterface := ...// some object whose class implements IMyInterfaceMyInterface := MyClass;MyInterface.P1;
end;

六、委托给类类型属性(Delegating to a Class-Type Property)

如果委托属性属于一个类的类型,则在搜索外层类及其祖先之前,先搜索该类及其祖先中实现指定接口的方法。因此,可以在属性指定的类中实现某些方法,而在声明属性的类中实现其他方法。方法解析子句可以按通常的方式用于解决歧义或指定特定方法。一个接口不能由多个类类型属性实现。例如 :

typeIMyInterface = interfaceprocedure P1;procedure P2;end;TMyImplClass = classprocedure 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;// ...
varMyClass: TMyClass;MyInterface: IMyInterface;
beginMyClass := TMyClass.Create;MyClass.FMyImplClass := TMyImplClass.Create;MyInterface := MyClass;MyInterface.P1;  // calls TMyClass.MyP1;MyInterface.P2;  // calls TImplClass.P2;
end;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/51788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【锐捷】OSPF 多区域配置

【实验名称】 配置 OSPF 多区域。 【实验目的】 配置 OSPF 多区域,理解 OSPF 层次型网络的特点。 【背景描述】 本实验拓扑图中有 3 台路由器,路由器在区域 0 和区域 1 中,路由器 B 在区域 0 和区域 30, 路由器 C 在区域 30。 【需…

Rocket消息存储

一、存储介质 ● 关系型数据库DB Apache下开源的另外一款MQ—ActiveMQ (默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化,通过简单的xmI配置信息即可实现JDBC消息存储。由于,普通关系型数据库(如Mysql)在单表数据量达到千万级别的情况下&a…

linux安装部署gitlab全教程,包含配置中文

linux安装部署gitlab全教程,包含配置中文 大家好,我是酷酷的韩~ 1.前期准备 安装包下载地址 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 我这里选择的这个gitlab-ce-15.7.3-ce.0.el7.x86_64.rpm 还有一些相关依赖包(地址等审核过我放到…

pdf编辑文字怎么编辑?这几种简单编辑方法看一看

pdf编辑文字怎么编辑?PDF文件是一种普遍的文档格式,但是在编辑时却比较困难。幸运的是,有许多PDF编辑器可以帮助我们轻松地编辑PDF文件。本文将介绍一些简单的PDF编辑方法,跟着我一起来看看吧! 第一种方法:…

docker for window更改到非系统盘的使用记录

1、使用Hyper-v模式的docker安装 2、安装docker for windows后安装目录没办法自己选择,固定在c盘 卸载后通过命令行方式设置软连接方式后重新安装来让其安装到软连接的d盘,解决c盘空间问题 mklink /j "C:\Program Files\Docker" "D:\Pr…

如何通过python来给手机发送一条短信?

要通过Python发送短信到手机,您可以使用不同的短信服务提供商的API。以下是一个使用Twilio和Sinch服务提供商的示例,您可以根据自己的选择来决定使用哪个。 使用Twilio发送短信: 首先,注册一个Twilio账户并获取您的账户SID、认证令牌和Twilio号码。 安装 twilio 包,如果您…

JavaFx 生成二维码工具类封装

之前星之音乐下载器有需要生成二维码功能,当时用的是一个开源库来实现的,但是没过多久,发现那个库依赖太多,有个http-client的依赖,把软件都搞大了一倍,而且有时候开发的时候下载依赖还报错,就想换个方案 于是在网上找了下解决方案,最终只需要依赖两个zxing的两个依赖即可实现…

JVM——垃圾回收器G1+垃圾回收调优

4.4 G1(一个垃圾回收器) 定义: 取代了CMS垃圾回收器。和CMS一样时并发的。 适用场景: 物理上分区,逻辑上分代。 相关JVM参数: -XX:UseG1GC-XX:G1HeapRegionSizesize-XX:MaxGCPauseMillistime 1) G1 垃圾回收阶段 三个回收阶段&#xff0…

kubeadm init 失败: failed to pull image k8s.gcr.io/etcd:3.4.13-0

一. kubeadm init 失败 报错: error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-apiserver:v1.19.3: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: reque…

基于JSP+Servlet+mysql员工权限管理系统

基于JSPServletmysql员工权限管理系统 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 项目类型:Java web项目 项目名称:基于JSPServlet的员工权限管理系统[qxxt] 项目架构:B/S架构 开发语言:Java语言 …

Solidity 合约安全,常见漏洞(第三篇)

Solidity 合约安全,常见漏洞(第三篇) ERC20 代币问题 如果你只处理受信任的 ERC20 代币,这些问题大多不适用。然而,当与任意的或部分不受信任的 ERC20 代币交互时,就有一些需要注意的地方。 ERC20&#…

Docker 安装rabbitmq:3.12-management

拉取镜像: docker pull rabbitmq:3.12-management mkdir -p /usr/local/rabbitmq chmod 777 /usr/local/rabbitmq docker run -id --restartalways --namerabbitmq -v /usr/local/rabbitmq:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_U…

如何在 Opera 中启用DNS over HTTPS

DNS over HTTPS(基于HTTPS的DNS)是一种更安全的浏览方式,但大多数 Web 浏览器默认情况下不启用它。了解如何在 Opera 浏览器中启用该功能。 您可能不知道这一点,但您的网络浏览器并不像您希望的那样私密或安全。您会看到&#xff…

助力品牌形象建设,FairGuard支持企业深度定制化

2022年,中国游戏市场实际销售收入与游戏用户规模出现近年来的首次下降,标志着游戏产业发展正式迈入存量时代。 存量市场时代,意味着游戏产品获取用户的难度逐渐加大,对于游戏的内容品质、技术实力和价值拓展等有了更高的要求。如…

C - 滑动窗口 /【模板】单调队列

Description 有一个长为 n 的序列 a,以及一个大小为 k 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。 例如: The array is [1,3,−1,−3,5,3,6,7] and k3。 Input 输入一共有…

初出茅庐的小李博客之STM32CubeMx配置USART1增加打印功能

1.创建基于STM32F03C8T6工程 1.1配置时钟 选择外部高速时钟源HSE 1.2配置系统时钟树使其达到最大时钟72MHz(最大系统时钟) 配置串口1 生成代码 具体工程配置可参考上几篇博客,地址 初出茅庐的小李博客之STM32CubeMx驱动WS2812B实现幻彩&a…

深入理解Linux权限管理:保护系统安全的重要措施

Linux操作系统以其稳定性、可靠性和灵活性而受到广泛使用。其中一个关键特性是其强大的权限管理系统,它可以保护系统资源和用户数据的安全性。本文将深入探讨Linux权限管理的概念、原则和实践,帮助您理解如何正确配置和管理权限,以确保系统的…

​亚商投资顾问 早餐FM/0825 8月24日起全面暂停进口日本水产品

01/亚商投资顾问 早间导读 中国证监会召开机构投资者座谈会,引导更多中长期资金入市海关总署:8月24日起全面暂停进口日本水产品财政部:加强财税支持政策落实,促进中小企业高质量发展 02/亚商投资顾问 新闻早餐 // 热点聚焦 //…

PyTorch DataLoader 报错 “DataLoader worker exited unexpectedly“ 的解决方案

注意:博主没有重写d2l的源代码文件,而是创建了一个新的python文件,并重写了该方法。 一、代码运行日志 C:\Users\Administrator\anaconda3\envs\limu\python.exe G:/PyCharmProjects/limu-d2l/ch03/softmax_regression.py Traceback (most r…

通过python在unity里调用C#接口

log: 背景 最近在做虚拟人底层驱动sdk测试,因为后端使用的是C#,我个人更倾向于python编程辅助测试工作,测试sdk需要通过开发提供的接口方法文档,通过传测试场景参数调用方法进行单元测试 技术&工具 项目语言 C# 项目工具 unity 测试…