回答实际问题标题中的问题: 你不能。:)
但是,如果我们退后一步,看看你试图解决的问题:
我有一个从 TFileStream 继承的类和一个从 TMemoryStream 继承的类。两者都实现了与读取数据完全相同的功能
我认为您错误地陈述了您的问题并正确地重新陈述它指向您需要的答案。:)
I have some structured data that I need to read from different sources (different stream classes).
流只是一堆字节。这些字节中的任何结构都取决于您如何读/写流。即在这种情况下,“如何”体现在您的功能中。所涉及的具体流类是TFileStream和TMemoryStream的事实从根本上不是问题的一部分。为TStream解决问题,然后为所有TStream派生类解决它,包括您现在正在处理的那些。
流类应该根据它们需要如何从特定位置(内存、文件、字符串等)读取/写入字节而不是这些字节中的任何特定结构来专门化。
与其创建必须复制结构知识的专用流类,您真正需要的是一个封装所涉及数据结构知识并能够将其应用于任何流的类。
读者班
解决这个问题的一种方法(最好的?)是实现一个封装您需要的行为的类。例如在“读者”类中。
TStuffReader = class
private
fStream: TStream;
public
constructor Create(aStream: TStream);
function ReadByte: byte;
function ReadWord: word;
function ReadWordBE: word;
function ReadDWord: longword;
function ReadDWordBE: longword;
function ReadString(Length: integer): string;
function ReadBlockName: string;
end;
此类还可能提供用于写入流的函数(例如,在这种情况下,您可以将其称为TStuffFiler,因为它不仅仅是一个读取器),或者您可能有一个单独的写入类,称为 TStuffWriter(例如例子)。
无论您选择实现它,这个阅读器类都将能够从/向任何 TStream派生类读取(和/或写入)结构化数据。对于这些函数来说,涉及到什么特定的流类应该是无关紧要的。
如果您的问题包括需要将流的引用传递给各种函数等,那么您可以将引用传递给阅读器类。reader 必须携带对所涉及的流的引用,但是以前您认为需要调用专用流类上的函数的代码只是使用 reader 函数。如果该代码还需要访问流本身,则阅读器可以在必要时公开它。
然后在将来,如果您发现自己需要从其他流类中读取此类数据(例如,如果您发现自己从数据库中检索数据,则为 TBLOBStream),您的TStuffReader (或您选择的任何名称)可以直接介入并执行无需您进行任何进一步的工作即可为您完成这项工作。
类助手非替代
类助手似乎提供了一种近似“多重继承”的机制,但应该避免。它们从未打算用于应用程序代码。
VCL 中类助手的存在与您所期望的完全一样,因为它们旨在用于框架和库中,并且 VCL 是一个框架库,因此它的使用与该用法完全一致。
但这并不是对它们适用于应用程序代码的认可,并且文档继续强制执行这一点。
类和记录助手提供了一种扩展类型的方法,但不应将它们视为开发新代码时使用的设计工具。对于新代码,您应该始终依赖正常的类继承和接口实现。
文档也很清楚适用于类助手的限制,但没有清楚地解释为什么这些会导致问题,这也许就是为什么有些人仍然坚持认为它们适合使用的原因。
在引入这些问题后不久,我在一篇博文中介绍了这些问题(同样的问题今天仍然适用)。事实上,正是这样一个问题,我写了很多关于这个主题的帖子。
似乎不愿意放弃这样一种观念,即只要你小心你的助手,你就不会遇到问题,那就是忽略一个事实,即无论你多么小心,你对助手的使用都可以如果您最终与他们共享代码,则会被其他人同样谨慎的使用所破坏。
Delphi 中没有比 VCL 本身更多的共享代码。
在 VCL 中使用(额外的)助手使您自己的助手遇到麻烦的可能性更大,而不是更少。即使您的代码在 VCL 的一个版本中与您自己的助手完美配合,下一个版本也可能会破坏事情。
远非建议更多地使用助手,它们在 VCL 中的扩散只是你应该避免使用它们的一个很好的理由。