-3

我是关于接口的新手。我用谷歌搜索了很多,但我不知道在以下情况下该怎么做。

我创建了多个接口,它们相互使用:

IPart = interface(IInterface)
  Function getName: string;
  procedure setName(aValue: string)
  property Name: string read getName write setname;
end;


IOfferLine= interface(iInterface)
  Function getPart: IPart;
  function getAmount: double;
  procedure setPart(aPart: IPart);
  procedure setAmount(value: double);
  property Amount: double read getAmount write setAmount;
  property Part: IPart read GetPart write setPart;
end;

IOffer= interface(iInterface)
  function getOffLines: tList<IOfferline>;
  procedure setOffLines(aList: tList<IOfferline>);
  property OffLines: tList<IOfferlines> read getOffLines write setOfflines;
end;

现在我想实现这些接口。

TPart = class(TInterfacedObject, IPart)
  private
    _Name: string;
    function getName: string;
    procedure setName(aValue: string);
  public
    property Name: string read getName write setName;
end;

TOfferLine = class(TInterfacedObject, IOfferLine)
  private
    _amount: double;
    _part: TPart;
    function getAmount: double;
    function getPart: tPart;
    procedure setAmount(aValue: double);
    procedure setPart(aPart: TPart);
  public
    property Amount: double read getAmount write setAmount;
    property Part: TPart read GetPart write SetPart;
  end;

TOffer = class(TInterfacedObject, IOffer)
  private
    _OfferLines: tList<TOfferline>;
    function getOffLines: tList<tOfferline>;
    procedure setOffLines(aList: tList<tOfferline>);
  public
    property offLines: tList<TOfferline> read getOffLines write setOffLines;
end;

我已经添加了实现。

function TOfferLine.getPart: tPart;
begin
  result := _part;
end;

但我仍然得到“缺少接口方法 IOfferline.GetPart 的实现;”

我不知道为什么。

4

2 回答 2

2

我不知道您要做什么,但是如果您没有编写如此混乱的代码,那将更容易阅读。但是感谢上帝,我们有一个源格式化程序。

您的代码中有几个问题:

First你有你的属性声明为 property OffLines: TList<IOfferline**s**>当你的接口被命名时IOfferline

然后TOfferline你有一个方法procedure setPart(aPart: TPart);应该是过程 setPart(aPart: IPart); 因为这就是您声明界面的方式。而你使用 TPart 的所有其他地方都应该是 IPart。

这同样适用于TOffer

这是您的代码的清理版本:

unit Unit20;

interface
uses
  Generics.Collections;

type
  IPart = interface(IInterface)
    function getName: string;
    procedure setName(aValue: string);
    property Name: string read getName write setName;
  end;

  IOfferLine = interface(IInterface)
    function getPart: IPart;
    function getAmount: double;
    procedure setPart(aPart: IPart);
    procedure setAmount(value: double);
    property Amount: double read getAmount write setAmount;
    property Part: IPart read getPart write setPart;
  end;

  IOffer = interface(IInterface)
    function getOffLines: TList<IOfferLine>;
    procedure setOffLines(aList: TList<IOfferLine>);
    property OffLines: TList < IOfferLine > read getOffLines write setOffLines;
  end;

  TPart = class(TInterfacedObject, IPart)
  private
    _Name: string;
    function getName: string;
    procedure setName(aValue: string);
  public
    property Name: string read getName write setName;
  end;

  TOfferline = class(TInterfacedObject, IOfferLine)
  private
    _amount: double;
    _part: TPart;
    function getAmount: double;
    function getPart: IPart;
    procedure setAmount(aValue: double);
    procedure setPart(aPart: IPart);
  public
    property Amount: double read getAmount write setAmount;
    property Part: IPart read getPart write setPart;
  end;

  TOffer = class(TInterfacedObject, IOffer)
  private
    _OfferLines: TList<TOfferline>;
    function getOffLines: TList<IOfferLine>;
    procedure setOffLines(aList: TList<IOfferLine>);
  public
    property OffLines: TList < IOfferLine > read getOffLines write setOffLines;
  end;

implementation

{ TOfferline }

function TOfferline.getAmount: double;
begin

end;

function TOfferline.getPart: IPart;
begin

end;

procedure TOfferline.setAmount(aValue: double);
begin

end;

procedure TOfferline.setPart(aPart: IPart);
begin

end;

{ TOffer }

function TOffer.getOffLines: TList<IOfferLine>;
begin

end;

procedure TOffer.setOffLines(aList: TList<IOfferLine>);
begin

end;

{ TPart }

function TPart.getName: string;
begin

end;

procedure TPart.setName(aValue: string);
begin

end;

end.
于 2015-08-13T09:51:59.413 回答
-1

编译器说缺少实现的原因仅仅是因为缺少实现。

您的IOfferLine接口声明了这个getPart方法:

IOfferLine= interface(iInterface)
  ..
  function getPart: IPart;
  ..
end;

但是您的实现类不提供此方法。您的类中的getPart方法被实现为返回对象引用,而不是接口引用:

TOfferLine = class(TInterfacedObject, IOfferLine)
private
  ..
  function getPart: tPart;
  ..
end;

您需要确保您的实现类实际上准确且准确地提供了它实现的接口所需的成员:

TOfferLine = class(TInterfacedObject, IOfferLine)
private
  ..
  function getPart: IPart;
  ..
end;

function TOfferline.getPart: IPart;
begin
  result := _part as IPart;
end;

但是,由于对OfferLine对象(在_part变量中)维护的Part的引用是一个对象引用,因此使用接口(通过getPart:IPart方法)获得的对该对象的引用可能会导致该Part对象被销毁,因为OfferLine中的对象引用不计入(字面意思)。

您当然可以通过将OfferLine持有的Part引用设置为接口引用本身来避免这种情况,但是如果没有整个对象模型的完整图片,很难说这是否有效。如果您的对象的生命周期是由问题中不明显的其他机制确保的,那么这可能不是问题,但如果到目前为止还没有特别考虑过,那么它可能确实需要解决。

尽管可以安全地进行操作,但作为一般规则,将对象引用和对同一对象的接口引用混合是一个问题的根源。

于 2015-08-13T23:59:09.140 回答