- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道如何按照以下要求扩展具有附加功能的类层次结构:1)我无法触及原来的层次结构2)我需要将新功能开发到不同的单元
以uClasses.pas单元中的以下类层次结构为例:
TBaseClass = class
ID : Integer;
Name : String;
end;
TDerivedClass = class(TBaseClass)
Age : Integer
Address : String
end;
我想将其他功能附加到类中,例如将其自身保存到文本(这只是一个示例)。所以我想象了以下单元uClasses_Text.pas:
uses uClasses;
Itextable = interface
function SaveToText: String;
end;
TBaseClass_Text = class(TBaseClass, Itextable)
function SaveToText: String;
end;
TDerivedClass_Text = class(TDerivedClass, ITextable)
function SaveToText: String;
end;
function TBaseClass_Text.SaveToText: String;
begin
result := Self.ID + ' ' + Self.Name;
end;
function TDerivedClass_Text.SaveToText: String;
begin
// SaveToText on derived class must call SaveToText from the "BaseClass" and then append its additional fields
result := ???? // Call to TBaseClass_Text.SaveToText. Or better, ITextable(Self.ParentClass).SaveToText;
result := result + Self.Age + ' ' + Self.Address;
end;
如何从 TDerivedClass_Text.SaveToText 中引用 SaveToText 的“基本”实现?也许以某种方式处理界面?
或者,对于这种情况,是否存在更好、更简洁的方法?
谢谢
最佳答案
正如 David 所指出的,您不能引用基类中不存在的方法。
使用类助手,可以用另一种方式解决您的问题。第一个类帮助器 TBaseClassHelper
添加了一个 SaveToText
函数,第二个类帮助器 TDerivedClassHelper
也添加了一个 SaveToText
函数。查看第二个 SaveToText
函数的实现。它调用继承的SaveToText
。
更新2
OP 希望针对不同的 SaveTo
实现使用单独的单元。在 David 和 Arioch 的评论的帮助下,事实证明类助手可以从其他类助手继承。这是一个完整的示例:
unit uClasses;
type
TBaseClass = class
ID: Integer;
Name: String;
end;
TDerivedClass = class(TBaseClass)
Age: Integer;
Address: String;
end;
<小时/>
unit uClasses_Text;
uses uClasses,uClasses_SaveToText,uClasses_SaveToIni,uClasses_SaveToDB;
type
ITextable = interface
function SaveToText: string;
function SaveToIni: string;
function SaveToDB: string;
end;
// Adding reference counting through an interface, since multiple inheritance
// is not possible (TInterfacedObject and TBaseClass)
TBaseClass_Text = class(TBaseClass, IInterface, ITextable)
strict private
FRefCount: Integer;
protected
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
TDerivedClass_Text = class(TDerivedClass, IInterface, ITextable)
strict private
FRefCount: Integer;
protected
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
implementation
uses Windows;
function TBaseClass_Text.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TBaseClass_Text._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TBaseClass_Text._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
end;
function TDerivedClass_Text.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TDerivedClass_Text._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TDerivedClass_Text._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
end;
<小时/>
unit uClasses_SaveToText;
interface
uses uClasses;
type
TBaseClassHelper = class helper for TBaseClass
function SaveToText: string;
end;
TDerivedClassHelper = class helper for TDerivedClass
function SaveToText: string;
end;
implementation
function TBaseClassHelper.SaveToText: string;
begin
Result := 'BaseClass Text info';
end;
function TDerivedClassHelper.SaveToText: string;
begin
Result := inherited SaveToText;
Result := Result + ' DerivedClass Text info';
end;
<小时/>
unit uClasses_SaveToIni;
interface
Uses uClasses,uClasses_SaveToText;
type
TBaseClassHelperIni = class helper(TBaseClassHelper) for TBaseClass
function SaveToIni: string;
end;
TDerivedClassHelperIni = class helper(TDerivedClassHelper) for TDerivedClass
function SaveToIni: string;
end;
implementation
function TBaseClassHelperIni.SaveToIni: string;
begin
Result := 'BaseClass Ini info';
end;
function TDerivedClassHelperIni.SaveToIni: string;
begin
Result := inherited SaveToIni;
Result := Result + ' DerivedClass Ini info';
end;
<小时/>
unit uClasses_SaveToDB;
interface
Uses uClasses,uClasses_SaveToText,uClasses_SaveToIni;
Type
TBaseClassHelperDB = class helper(TBaseClassHelperIni) for TBaseClass
function SaveToDB: string;
end;
TDerivedClassHelperDB = class helper(TDerivedClassHelperIni) for TDerivedClass
function SaveToDB: string;
end;
implementation
function TBaseClassHelperDB.SaveToDB: string;
begin
Result := 'BaseClass DB info';
end;
function TDerivedClassHelperDB.SaveToDB: string;
begin
Result := inherited SaveToDB;
Result := Result + 'DerivedClass DB info';
end;
<小时/>
program TestClasses;
uses
uClasses in 'uClasses.pas',
uClasses_Text in 'uClasses_Text.pas',
uClasses_SaveToText in 'uClasses_SaveToText.pas',
uClasses_SaveToIni in 'uClasses_SaveToIni.pas',
uClasses_SaveToDB in 'uClasses_SaveToDB.pas';
var
Textable: ITextable;
begin
Textable := TDerivedClass_Text.Create;
WriteLn(Textable.SaveToText);
WriteLn(Textable.SaveToIni);
WriteLn(Textable.SaveToDB);
ReadLn;
end.
更新1
阅读您关于需要实现 SaveToText
的几个方面的评论,我提出了一个简单的背负式解决方案:
type
ITextable = interface
function SaveToText: String;
end;
TMyTextGenerator = class(TInterfacedObject,ITextable)
private
Fbc : TBaseClass;
public
constructor Create( bc : TBaseClass);
function SaveToText: String;
end;
{ TMyTextGenerator }
constructor TMyTextGenerator.Create(bc: TBaseClass);
begin
Inherited Create;
Fbc := bc;
end;
function TMyTextGenerator.SaveToText: String;
begin
Result := IntToStr(Fbc.ID) + ' ' + Fbc.Name;
if Fbc is TDerivedClass then
begin
Result := Result + ' ' + IntToStr(TDerivedClass(Fbc).Age) + ' ' +
TDerivedClass(Fbc).Address;
end;
end;
在不同的单元中使用相同的模式实现 TSaveToIni、TSaveToDB 等。
关于delphi - 扩展delphi类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11883474/
我正在尝试将多个水平链接的 Button 和 TextView 垂直链接为 View 集,但仍保持平面 View 层次结构。这是我的初始布局和代码:
到目前为止,我已经在Google BigQuery上训练了几种模型,目前我需要查看模型的外观(即架构,损失函数等)。 有没有办法获取这些信息? 最佳答案 仔细阅读文档后,我可以说该功能尚不存在。我什至
本文实例讲述了PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)。分享给大家供大家参考,具体如下: 前言: 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个
我是一名优秀的程序员,十分优秀!