很多接口在delphi中传承

时间:2017-05-22 23:21:13

标签: oop delphi interface

我希望制作一些D类传统并实现接口A,B和C的所有属性和方法。请帮我解决Delphi中的一个例子。

我使用的是Delphi Xe7 一个类如何实现多个接口? 我正在尝试这样的事情:

Unit1
Type
   IRefresher = Interface
      ['{B289720C-FFA4-4652-9F16-0826550DFCF9}']
      procedure Refresh;
      function getRefreshed: boolean;
      property Refreshed:Boolean read getRefreshed;
   End;
Unit2
Type
   IRecorder = Interface
      ['{AB447097-C654-471A-A06A-C65CE5606721}']
      procedure Reader;
      procedure Writer;
   end;
Unit3
ICustomer=Interface ['{F49C0018-37DA-463D-B5B4-4ED76416C7D4}']
    procedure SetName(Value:String);
    procedure SetDocument(Value:String);
    function getName:String;
    function getDocument:String;
End;
  Unit4
    Uses Unit1,Unit2,Unit3;
        TGovernmentCustomer = class(TInterfacedObject, ICustomer, IRecorder,
 IRefresher)
  a: String;
   public
{$REGION 'Customer'}
      procedure SetName(Value: String); override;
      procedure SetDocument(Value: String);
      function getName: String; override;
      function getDocument: String; override;
{$ENDREGION}
{$REGION 'Recorder'}
      procedure Reader; override;
      procedure Writer; override;
{$ENDREGION}
{$REGION 'Refresher'}
      procedure Refresh; override; 
      function getRefreshed: boolean; override;
{$ENDREGION}
   End;

它不起作用,因为有许多错误,例如“在基类中找不到刷新”,

2 个答案:

答案 0 :(得分:1)

从代码中删除override字,因为interface方法实现没有明确的method binding directive。您在代码中使用的override指令仅适用于即将实施的祖先类的virtualabstract)或dynamic类方法目前的班级。

这是一个示例,它演示了override指令的含义以及使用接口的伪抽象类(来自代码的示例):

type
  ICustomer = interface
  ['{F49C0018-37DA-463D-B5B4-4ED76416C7D4}']
    procedure SetName(Value: string);
  end;

  IRefresher = interface
  ['{B289720C-FFA4-4652-9F16-0826550DFCF9}']
    procedure Refresh;
  end;

  // sort of "abstract" class (not precisely) that does not yet "implement"
  // the methods of the interfaces, only "includes" the interfaces
  TAnyCustomer = class(TInterfacedObject, ICustomer, IRefresher)
  private
    FSomething: string;
  public
    // though the interfaces are "included" as a part of this class, their
    // method implementation is not yet specific (missing implementantion
    // exception is raised only, which is self-explaining, I'd say); that
    // "virtual" directive of the following class methods lets this class'
    // descendants "override" them to write the specific implementation
    procedure SetName(Value: string); virtual;
    procedure Refresh; virtual;
  end;

  // specific implementation of the class defined above; here you "override"
  // the virtual methods of the "abstract" class defined above and implement
  // the specific behavior of the class
  TGovernmentCustomer = class(TAnyCustomer)
  public
    // "override" the ancestor's class method behavior and write a specific
    // implementation (which finally implements some specific functionality
    // here)
    procedure SetName(Value: string); override;
    procedure Refresh; override;
  end;

implementation

procedure TAnyCustomer.SetName(Value: string);
begin
  raise ENotImplemented.Create('Ouch! You missed to implement me!');
end;

procedure TAnyCustomer.Refresh;
begin
  raise ENotImplemented.Create('Ouch! You missed to implement me!');
end;

procedure TGovernmentCustomer.SetName(Value: string);
begin
  ShowMessage('I''m a government customer. How can I increase your budget?');
end;

procedure TGovernmentCustomer.Refresh;
begin
  ShowMessage('Tell someone I''m fresh!');
end;

答案 1 :(得分:1)

您至少有3个实施选项:

1)虚拟和抽象方法。在这种情况下,您无法实例化此类,并且必须覆盖后代类中的抽象方法。这样的方法看起来像这样:

type
  TGovernmentCustomer = class(TInterfacedObject, ICustomer, IRecorder, IRefresher)
    a: String;
  public
    procedure SetName(Value: String); virtual; abstract;
  end;

一旦方法是抽象的,就没有实现。

2)虚拟方法。在这种情况下,您可以实例化此类,并且可以覆盖后代类中的某些虚方法。这样的方法看起来像这样:

type
  TGovernmentCustomer = class(TInterfacedObject, ICustomer, IRecorder, IRefresher)
    a: String;
  public
    procedure SetName(Value: String); virtual;
  end;

  implementation

  procedure TGovernmentCustomer.SetName(Value: String);
  begin
    // do something here. You can also leave it empty
  end;

3)静态方法。在这种情况下,您可以实例化此类,并且不能覆盖后代类中的静态方法。这样的方法看起来像这样:

type
  TGovernmentCustomer = class(TInterfacedObject, ICustomer, IRecorder, IRefresher)
    a: String;
  public
    procedure SetName(Value: String);
  end;

  implementation

  procedure TGovernmentCustomer.SetName(Value: String);
  begin
    // do something here. This will be the behavior of all instances of this class and descendant classes if they exist
  end;

最后一点:Case(3)表现最佳。在接口上调用虚方法会导致性能损失,这可能与您的特定应用程序相关,也可能不相关。

PS:正如Stefan所指出的,我与另一个SO问题的联系是错误的。但是,您可以阅读Andreas Hausladen博客通过界面调用的虚拟方法的性能:http://andy.jgknet.de/blog/2016/05/whats-wrong-with-virtual-methods-called-through-an-interface/