Interfaces

Top  Previous  Next

Interfaces  are supported  using  the  classic  Delphi  syntax  (except the GUID  part  which  is  not supported). 

 

Interfaces can define properties, which are syntax sugar to their methods. They can be implemented by Classes.

 

Pas2JS fully supports interfaces. There is no need for TInterfacedObject, interfaces can be applied directly to TObject since JavaScript does not have a mechanism for observing reference counts.

 

 

The Interface keyword is used in two different ways: 

 

Version 1: It starts the definition of external interface of a Unit. Declarations here are externally visible by other units. All of these declarations must be implemented in the Implementation section. The Uses statement, if present, 

must be at the start. 

 

Version 2: In Object Oriented programming, we often use Abstract class methods in a base class as a placeholder. 

All derived classes must implement these methods. 

 

Taking this one step further, an Interface defines a grouping of just abstract properties and methods. 

It provides a template for a class to use to ensure consistency. It is like a class with only abstract methods. 

It has the benefits that classes can be based on one parent class, and implement one or more interfaces. 

It adds a predictable flavour of operation to each class that implements the interface. 

 

Note: The class implementing an interface can be derived from any parent. There is no TInterfacedObject class. 

 

 

An interface example 

Like many ideas, an example is the best way to illustrate the concepts. We'll do it in stages to keep things as simple as possible.

 

 

First, let us define a interface.

Interface, it makes it easier for the programmer to be disciplined in developing the application; all of the classes have 

an additional set of methods that are identical. And Pas2JS insists that all of the methods in an interface are implemented.

 

 

unit uTest;

 

interface

 

uses 

  SmartCL.System;

 

type

    // An interface definition

  IMyInterface = interface

    procedure myInternalMethod;

  end;

 

type

  // An interface definition

  IVehicle = Interface(IInterface)

    // Properties and their functions

    function GetAge   : Integer;

    function GetMiles : Integer;

    property age   : Integer read GetAge;

    property miles : Integer read GetMiles;

 

    // Non-property function

    function GetValue : Float;

  end;

 

implementation

 

end.

Our interface uses the standard IInterface interface definition as a base. Interfaces definitions are like class definitions with 

all abstract elements. We do not have to declare them as abstract - they are by default.

 

This interface adds two properties. The the power and benefit of interfaces is the uniformity across potentially very different 

classes.

 

 

How to implement a interface?

unit uTestImpl;

 

interface

 

uses 

  SmartCL.System, uTest;

 

type

 TMyObject = class(TObject,IMyInterface)

   public

   { IMyInterface Implementation }

   procedure myInternalMethod;

end;

 

// Implement this interface in a car class

// Note that there is no TInterfacedObject class.

  TCar = Class(IVehicle)

  private

    fAge, fMiles : Integer;

    fCarType : string;

    function GetAge   : Integer;

    function GetMiles : Integer;

  public

    property age     : Integer read GetAge;

    property miles   : Integer read GetMiles;

    property carType : string  read fCarType;

 

    // Non-property function

    function GetValue : Float;

  published

    constructor Create(age, miles : Integer; carType : string);

  end;

 

implementation

 

{ TMyObject }

procedure TMyObject.myInternalMethod;

begin

  WriteLn('Hello warleyalex');

end;

 

// Car constructor

constructor TCar.Create(age, miles: Integer; carType: string);

begin

  // Save parameters

  fAge     := age;

  fMiles   := miles;

  fCarType := carType;

end;

 

// Get the age of the car

function TCar.GetAge: Integer;

begin

  Result := fAge;

end;

 

// Get the mileage of the car

function TCar.GetMiles: Integer;

begin

  Result := fMiles;

end;

 

// Calculate the car value

function TCar.GetValue: Float;

begin

  Result := 10000.0 - ((age * miles)/10.0);

end;

 

end.

Note that:

·We place the function used by the interface GetAge and GetMIles property in the private section. We only want the caller to use the property. 
·We must declare the GetAge and GetMiles functions.
·We must not forget to set this Age, Miles and CarType values. We'll do it in the constructor:
 

How to instantiate our Car object?

unit Form1;

 

interface

 

uses 

  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 

  uTestImpl,

  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button;

 

type

  TForm1 = class(TW3Form)

    procedure W3Button1Click(Sender: TObject);

  private

    {$I 'Form1:intf'}

  protected

    procedure InitializeForm; override;

    procedure InitializeObject; override;

    procedure Resize; override;

  end;

 

implementation

 

{ TForm1 }

 

procedure TForm1.W3Button1Click(Sender: TObject);

var

  car : TCar;

  obj : TMyObject;

begin

obj := TMyObject.Create();

obj.myInternalMethod;

 

car := TCar.Create(12076'Honda Jazz');

 

// Show the current value of this car

WriteLn(Format('My %s car is %d years old, %d miles, value %d',

                 [car.carType, car.age, car.miles, car.GetValue]));

 

end;

 

procedure TForm1.InitializeForm;

begin

  inherited;

  // this is a good place to initialize components

end;

 

procedure TForm1.InitializeObject;

begin

  inherited;

  {$I 'Form1:impl'}

end;

 

procedure TForm1.Resize;

begin

  inherited;

end;

 

initialization

  Forms.RegisterForm({$I %FILE%}, TForm1);

{ TMyObject }

 

end.

Hello warleyalex

My Honda Jazz car is 1 years old, 2076 miles, value 9792.4