gpt4 book ai didi

delphi - 多态性和性质

转载 作者:行者123 更新时间:2023-12-03 15:51:58 25 4
gpt4 key购买 nike

我正在尝试使用多态性并创建一个属性,该属性应该根据对象的类型返回不同的类型。

为什么下面的代码会出现编译器警告:

[警告:使用抽象方法“SetValue”构造类“TTimeField”]

更重要的是,如何才能完成这项工作,以便在创建 TTimeField 时可以为 Value 分配 TDateTime?事实上,有一条关于“类型不匹配”的消息。

  TBaseField = class
private
function GetValue: string; virtual; abstract;
procedure SetValue(AValue: string); virtual; abstract;
public
property Value: string read GetValue write SetValue;
end;

{ TTimeField }

TTimeField = class(TBaseField)
private
FValue : TDateTime;
function GetValue: TDateTime; override;
procedure SetValue(AValue: TDateTime); override;
public
property Value: TDateTime read GetValue write SetValue;
end;

实现

function TTimeField.GetValue: TDateTime;
begin
Result:= FValue;
end;

procedure TTimeField.SetValue(AValue: TDateTime);
begin
FValue:= AValue;
end;

编辑:下面,通过使用字符串,我实现了所需的功能,但如果上面的代码有效,则意味着性能的提高。

TBaseField = class
private
procedure SetStrValue(AValue: string); virtual; abstract;
function GetStrValue: string; virtual; abstract;
public
property AsString: string read GetStrValue write SetStrValue;
end;

TTimeField = class(TBaseField)
private
FValue : TDateTime;
function GetStrValue: string; override;
procedure SetStrValue(AValue: string); override;
public
property AsString: string read GetStrValue write SetStrValue;
end;

function TTimeField.GetStrValue: string;
begin
Result:= DateTimeToStr(FValue);
end;

procedure TTimeField.SetStrValue(AValue: string);
begin
FValue:=StrToDateTime(AValue);
end;

最佳答案

我认为你的问题是你实际上并没有重写任何方法;你的新方法有不同的签名。因此,它实际上是一个过载。在您的示例中,有 TBaseField对你没有任何帮助。该子类不使用它的任何方法,也不提供任何额外的功能。

多态性是指改变给定接口(interface)的实现(如方法签名),而调用者不需要知道这一点。看看您的示例,您可能不一定在寻找多态性,而是在寻找一种用尽可能少的代码为各种数据类型实现类似方法/属性的方法。这就是泛型通常被证明更有用的地方。

假设所有字段类都需要存储自己类型的值,该值应该可以设置和检索。然后你可以定义一个通用的 TField<T>哪里T是字段应使用的数据类型的“占位符”。您将能够给它一个 getter 和 setter,以及一个属性,这也将是通用的。因此,您只需为最终将使用的各种字段定义一次。这些方法可以包含所有字段共享的任何逻辑。但是,您仍然可以对泛型类型进行子类化,以向特定类型添加特定功能,或者隐藏您依赖泛型的事实。

一个简单的例子:

type
TField<T> = class
private
FValue: T;
protected
function GetValue: T; virtual;
procedure SetValue(const AValue: T); virtual;
public
property Value: T read GetValue write SetValue;
end;

TDateTimeField = TField<TDateTime>;

TTrimmingStringField = class(TField<string>);
protected
function SetValue(const AValue: string); override;
end;

// Now use these fields as you'd expect

implementation

{ TField<T> }

function TField<T>.GetValue: T;
begin
Result := FValue;
end;

procedure TField<T>.SetValue(const AValue: T);
begin
FValue := AValue;
end;

{ TTrimmingStringField }

procedure TTrimmingStringField.SetValue(const AValue: string);
begin
inherited SetValue(Trim(AValue));
end;

关于delphi - 多态性和性质,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32340445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com