加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

扩展delphi类层次结构

发布时间:2020-12-15 09:25:09 所属栏目:大数据 来源:网络整理
导读:我想知道如何使用其他功能扩展类层次结构,遵循以下要求: 1)我无法触及原始层次结构 2)我需要将新功能开发到不同的单元中 以uClasses.pas单元中的以下类层次结构为例: TBaseClass = class ID : Integer; Name : String;end;TDerivedClass = class(TBaseClas
我想知道如何使用其他功能扩展类层次结构,遵循以下要求:
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.

更新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,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_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等,在不同的单元中使用相同的模式.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读