Delphi中重新引用和覆盖指令的意义是什么? [英] What is the meaning of the reintroduce and override directives in Delphi?

查看:132
本文介绍了Delphi中重新引用和覆盖指令的意义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

覆盖 重新引入 指令?而且,我应该在覆盖的方法中不要使用 继承 关键字。

What is the difference between the override and reintroduce directives? And when should I not use the inherited keyword in overridden methods?

推荐答案

参考Jim的答案,这是非常好的BTW,只描述了使用指令的时间和地点。答案的另一部分是为什么还需要?许多语言在没有他们的情况下相处得很好,对吧?在设计Delphi对象Pascal语言的方面时,OOP(面向对象编程)已经成为主流的几年。在这段时间里,观察到使用许多使用这些概念(Turbo Pascal,C ++等)的语言来开发应用程序框架,受到我所谓的版本2问题的困扰。

The reference to Jim's answer, which was excellent BTW, only described the when and where to use the directives. Another part of the answer is why are they needed anyway? Many languages get along just fine without them, right? When designing aspects of the Delphi Object Pascal Language, OOP (Object Oriented Programming) had been in the mainstream for several years. During this time it was observed that using many of the languages that had adopted those concepts (Turbo Pascal, C++, etc..) to develop application frameworks suffered from what I called the "version 2" problem.

假设您使用语言X开发了一个令人敬畏的框架,并将其作为版本1发布。您的用户可以做到这一点,并且它被大量使用。与成功融合,您决定发布版本2更加惊人。你特别确保它完全向后兼容。突然间,用户开始报告奇怪的行为。他们自己的虚拟方法在奇怪的时候被叫。许多人报告说,他们的旧代码不会用新版本编译。奇怪。所有相同的对象,方法和功能仍然存在。你所做的只是添加一些虚拟方法到一些基类,一些新的对象类型和一些新的可选功能。发生了什么?

Suppose you developed an awesome framework using language X and released it as version 1. Your users raved at all it could do and it became heavily used. Flush with success, you decide to release version 2 with even more awesomeness. You specifically made sure it was fully backward compatible. Suddenly, you users started reporting strange behaviors. Their own virtual methods were being called at strange times. Many reported that their old code would not compile with the new version. Strange. All the same objects, methods, and functionality still remained. All you did was add a few virtual methods to some base classes, some new object types, and some new optional functionality. What happened?

覆盖和重新引入指令用于消除此问题,要求为了实际覆盖虚拟方法,您必须使用替代伪指令代替虚拟伪指令。如果你碰巧介绍你自己的虚拟方法,它与你祖先的一个虚拟方法有着同样的名字,编译器就会警告你,但仍然会做正确的事情。在这种情况下,使用重新引入,不仅可以抑制该警告,还可以在您打算这样做的源中记录。

The override and reintroduce directives serve to eliminate this problem by requiring that in order to actually override a virtual method you must use the override directive in place of the virtual directive. If you happen to introduce your own virtual method that has the same name as one of your ancestors' virtual methods, the compiler now warns you, but will still do the right thing. In this case, using reintroduce, not only suppresses that warning, it also serves to document in the source you intended to do that.

如果没有重写和重新引入指令,将无法不断地发展你的框架,而不用担心破坏你所有的用户。如果您的用户每次发布新版本时都必须进行大量修改,那么他们将不愿采用新版本。最后,使用override还允许框架设计者在不破坏用户代码的情况下更改祖先的虚拟类型。例如,在Delphi中,许多方法被标记为动态,它是一种基于表的运行时方法查找形式的多态。它的执行速度不如常规虚拟机那么快,因此通常用于很少被覆盖的方法和/或对用户操作的响应,而额外的开销从未被注意到。假设在框架的V1中,方法被标记为动态,但实际上它最终被覆盖并被称为比您想要的更多。在V2中,您可以将其更改为虚拟,而不用担心用户的代码被破坏。

Without the override and reintroduce directives, you would not be able to continually evolve your framework without fear of breaking all your users. And if your users had to make massive modifications every time a new version is released, then they would be loathe to adopt the new version. Finally, using "override" also allows the framework designer to change the type of virtual in the ancestors without breaking user code. For instance, in Delphi many methods are marked "dynamic" which is a table-based runtime method lookup form of polymorphism. It's doesn't perform quite as fast as a regular virtual so it is usually used for methods that are rarely overridden and/or are responses to user actions where the extra overhead is never noticed. Suppose in V1 of the framework a method was marked "dynamic" but in practice it ended up being overridden and called more than you intended. In V2, you could change it to "virtual" without fear of user's code being broken.

Delphi的Object Pascal语言不是识别此问题的唯一语言。 C#需要使用覆盖指令的完全相同的原因。 C ++标准委员会终于认识到了这个问题,正在修改语言来支持它。在C ++中,如果一个方法的名称和参数列表与祖先的虚拟对象匹配,那么它是一个覆盖(即使你不在后代上说虚拟)。对于即将到来的新C ++标准,如果指定虚拟,并且签名不匹配,那么它是在当前类中引入的新的虚拟方法。如果与祖先有签名匹配,并且作者没有打算重写,那么new关键字用于告诉编译器这是一个新的虚拟为这个类。

Delphi's Object Pascal language isn't the only language to recognize this problem. C# requires the use of an "override" directive for the exact same reason. The C++ standards committee is finally recognizing the problem and are modifying the language to support it... sort of. In C++, if a method's name and parameter list matches an ancestor's virtual, then it is an override (even if you don't say "virtual" on the descendant!). For the upcoming new C++ standard, if you specify "virtual" and the signatures don't match then it is a new virtual method introduced on current class. If there is a signature match with the ancestor and the writer didn't intend to override, then the "new" keyword is used to tell the compiler that this is a new virtual for this class.

这篇关于Delphi中重新引用和覆盖指令的意义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆