-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

あなたが何をしようとしているのかわかりませんが、コードをそれほど乱雑に書かなければ、読みやすくなります。しかし、Source フォーマッタがあることを神に感謝します。

あなたのコードにはいくつかの問題があります:

Firstproperty OffLines: TList<IOfferline**s**>インターフェイスの名前が付けられている間、プロパティが宣言されて いますIOfferline

次に、プロシージャ setPart(aPart: IPart); である必要がTOfferlineあるメソッドがあります。procedure setPart(aPart: TPart);それがあなたのインターフェースを宣言した方法だからです。また、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 に答える