Difference between revisions of "How To Use Interfaces"

From Lazarus wiki
Jump to navigationJump to search
(New page: Copy the text below and it will demonstrate how to use interfaces to write less code, avoid code repetition,..., this is a fully working program. ---- <pre> program interfacesygenerics; {...)
 
(Category and code highlighting)
Line 1: Line 1:
 
Copy the text below and it will demonstrate how to use interfaces to write less code, avoid code repetition,..., this is a fully working program.
 
Copy the text below and it will demonstrate how to use interfaces to write less code, avoid code repetition,..., this is a fully working program.
----
+
 
<pre>
+
 
program interfacesygenerics;
+
<delphi>program interfacesygenerics;
  
 
{$mode objfpc}{$H+}
 
{$mode objfpc}{$H+}
Line 121: Line 121:
 
     writeln('Double GMax:', TFakeClassDouble.gmax(23.89,56.5));
 
     writeln('Double GMax:', TFakeClassDouble.gmax(23.89,56.5));
 
     readln;
 
     readln;
end.
+
end.</delphi>
</pre>
 
  
----
+
[[Category:Tutorials]]

Revision as of 15:18, 18 December 2010

Copy the text below and it will demonstrate how to use interfaces to write less code, avoid code repetition,..., this is a fully working program.


<delphi>program interfacesygenerics;

{$mode objfpc}{$H+}

const

 STestInterface = '{3FB19775-F5FA-464C-B10C-D8137D742088}';

type

 ITestInterface = interface
   [STestInterface]
   procedure DoSomething;
   procedure DoItAll;
 end;
 { Base class Start }
 TBaseObject = class(TInterfacedObject)
   procedure DoAll;
 end;
 procedure TBaseObject.DoAll;
 begin
   Writeln('TBaseObject DoAll !');
 end;
 { Base class End }

type

 { THook Start}
 //Interface implementation on a derived class
 THook = class(TBaseObject, ITestInterface)
   procedure DoSomething;
   //Contrary to what is stated on the FPC reference manual
   //it's now possible to use aliases to indicate
   //interface implementations
   procedure ITestInterface.DoItAll = DoAll;
 end;
 procedure THook.DoSomething;
 begin
   Writeln('THook Doing something !');
 end;
 { THook End}

type

 { TRealClass Start }
 TRealClass = class(TBaseObject, ITestInterface)
 private
   FHook: ITestInterface;
 public
   constructor Create;
   destructor Destroy; override;
   //Here we tell the compiler that our class
   //interface implementation is provided by
   //a member field wich we initialize in this case
   //on the constructor
   property Hook: ITestInterface read FHook implements ITestInterface;
 end;
 constructor TRealClass.Create;
 begin
   //Creating our interface implementor
   FHook := THook.Create;
 end;
 destructor TRealClass.Destroy;
 begin
   //Releasing our interface implementor
   THook(FHook).Free;
   inherited Destroy;
 end;
 { TRealClass End }

type

   //An example of how to use generics to write
   //general use like procedures
   //as a bonus they are namespaced by the classname
   //disadvantage: can't be overloaded
   generic TFakeClass<_GT> = class
     class function gmax(a,b: _GT):_GT;
   end;
   TFakeClassInt = specialize TFakeClass<integer>;
   TFakeClassDouble = specialize TFakeClass<double>;
   class function TFakeClass.gmax(a,b: _GT):_GT;
   begin
        if a > b then result := a
        else result := b;
   end;


var

 R: TRealClass;
 I: ITestInterface;

begin

 Writeln('Using regular interfaces');
 R := TRealClass.Create;
 //callign the interfaced function directly
 R.DoAll;
 //Calling through the interface
 if R.GetInterface(STestInterface, I) then
   begin
     Writeln('Got interface OK. Calling it');
     I.DoSomething;
     I.DoItAll;
   end
   else
     Writeln('Interface not implemented !');


   //using the generated generics function
   writeln('Integer GMax:', TFakeClassInt.gmax(23,56));
   writeln('Double GMax:', TFakeClassDouble.gmax(23.89,56.5));
   readln;

end.</delphi>