Delphi 为什么';t后代';抽象基类的s版本';调用什么方法?

Delphi 为什么';t后代';抽象基类的s版本';调用什么方法?,delphi,interface,abstract,Delphi,Interface,Abstract,我试图创建一个简单的类THistory,它有一个过程,该过程采用一个抽象基类,该基类实现一个简单接口 下面的代码可以编译,但是THistory类调用基类HistoryRecords abstract Insert proc,而不是传入的子类Insert proc。我错过了什么 谢谢你的帮助 unit uHistory; interface uses Dialogs; type IHistoryRecord = interface ['{67C90064-1667-4DE0-AF52-

我试图创建一个简单的类THistory,它有一个过程,该过程采用一个抽象基类,该基类实现一个简单接口

下面的代码可以编译,但是THistory类调用基类HistoryRecords abstract Insert proc,而不是传入的子类Insert proc。我错过了什么

谢谢你的帮助

unit uHistory;

interface

uses Dialogs;

type

IHistoryRecord = interface
  ['{67C90064-1667-4DE0-AF52-11B6E5A00892}']
  procedure Insert();
end;

THistoryRecord = class abstract(TInterfacedObject, IHistoryRecord)
  procedure Insert(); virtual; abstract;
end;

THistory = class(TObject)
  public
  procedure Add(pHistoryRecord : THistoryRecord);
end;

TAlarmHistoryRecord = class(THistoryRecord)
  procedure Insert();
end;

implementation

{ THistory }

procedure THistory.Add(pHistoryRecord: THistoryRecord);
begin
  pHistoryRecord.Insert();
end;

{ TAlarmHistoryRecord }

procedure TAlarmHistoryRecord.Insert;
begin
  MessageDlg('Alarm History Record - Insert Method', mtInformation, [mbOK], 0);
end;

end.

Usage
procedure TForm1.Button1Click(Sender: TObject);
var
  lHistory : THistory;
  lHistoryRecord : TAlarmHistoryRecord;
begin

  lHistory := THistory.Create();

  lHistoryRecord := TAlarmHistoryRecord.Create();

  // I want this to call the TAlarmsHistoryRecord.Insert proc not the
  // HistoryRecord base class Insert proc.
  lHistory.Add(lHistoryRecord);

end;

您错过了覆盖:

TAlarmHistoryRecord = class(THistoryRecord)
  procedure Insert(); override;
end;

您缺少
TAlarmHistoryRecord
方法声明中的
override
指令,即它应该是

procedure Insert(); override;

实际上,编译器应该警告您该方法隐藏了继承的方法。

很抱歉,您的回答有点晚了,不仅应该有关于隐藏基类的虚拟方法的警告,还应该有关于实例化仍然有抽象方法的类的警告!永远不要忽略编译器警告,肖恩。当然,要查看提示和警告,必须先启用提示和警告。:)实现接口的抽象类是设计上的废话。使用抽象类或接口,而不是两者都使用。在本例中,@Serg,您是对的:因为THistoryRecord只有一个方法,而且它没有实现,所以从这一点出发而不是直接实现IHistoryRecord没有任何好处。不过,在其他情况下,抽象类为接口的一部分提供默认实现可能很有用,因此子体只能专门化必要的部分。TInterfacedObject就是一个很好的例子;它实现了IUnknown的细节,因此其他类不必这样做,但是没有理由直接实例化TInterfacedObject,因此它本质上是抽象的。另一方面,由于接口类型从未在代码的可执行部分中被引用(仅在基类声明中),因此它与这个问题并不相关。没有任何东西可以通过接口访问类,因此该接口是个麻烦。@Rob,正如您所说的TInterfacedObject实现了
IUnknown
方法。设计无意义是将这些方法声明为
virtual;摘要
。我看没有理由这么做。@Serg抽象类或具体类,声明任何一种形式的类都支持接口总是有意义的。