How does a class implement an interface in Pascal
Typically, interfaces achieve abstraction. They serve as blueprints or skeletons for designing classes.
An interface defines a common set of methods that must be defined by an implementing class. It includes only the declaration of these methods, that defines the operations that can be performed or the behavior of the class implementing it.
Different classes can implement the same interface according to their requirements.
In order to implement an interface in Pascal, it is important to note the following:
In Pascal, there are two commonly used modes of operation for interfaces—
andDELPHI Delphi compatibility mode .OBJFPC The original Free Pascal compiler mode including classes, interfaces and exceptions All interface members are public.
An interface instance cannot be created directly. Instead, a class implementing the interface must be created. There is no constructor or destructor.
An interface cannot be implemented in part; it must be implemented in full.
Within a class, interface methods can be aliased.
An interface that inherits from another interface should contain both the methods from the parent interface as well as the methods explicitly listed in the interface definition. In such case, It is mandatory for a class implementing an interface to implement all members of the interface as well as the methods of the parent interface(s).
Following are some examples showing how interfaces work:
Code example 1
This example illustrates what is a Pascal Interface and how to implement it:
program hello;{$mode objfpc}typevehiculeInterface = InterfaceFunction changeSpeed : Integer;Function startEngine : Integer;end;carClass = Class(TInterfacedObject,vehiculeInterface)Function changeSpeed : Integer;Function startEngine : Integer;Function changeColor : Integer;end;Function carClass.changeSpeed : Integer;beginResult := 5;end;Function carClass.startEngine : Integer;beginResult := 10;end;Function carClass.changeColor : Integer;beginResult := 20;end;varmyCar: carClass;beginwriteln('Start...');myCar:=carClass.create;writeln('myCar.changeSpeed = ',myCar.changeSpeed());writeln('myCar.startEngine = ',myCar.startEngine());writeln('myCar.changeColor = ',myCar.changeColor());writeln('End...');end.
Let's go through the code widget above:
Line 1: It refers to the program header. It's used for backward compatibility, and it is ignored by the compiler.
Line 2: Here, we direct the compiler to allow defining classes.
Lines 5–8: We use the
Interfacekeyword to define an interface,vehiculeInterface, comprising two member functions—changeSpeedandstartEngine.Lines 10–14: We define a
carClassclass implementing the interface previously declared. To avoid errors in compilation, we should inherit as well from a base object,TInterfacedObject. This class includes the two functions already defined in the interface in addition to a local member function,changeColor.Lines 16–27: We define the functions included within the class.
Lines 28–29: We declare a variable
myCarhaving as type the class already defined.Line 32: We create an instance of the class
carClassand store it in themyCarvariable previously declared.Lines 33-35: We invoke the functions included within the class and display their respective results.
Code example 2
This example aims to highlight the error returned by the compiler once it matches the methods of the class, missing one method startEngine, to those defined in the interface.
program hello;{$mode objfpc}typevehiculeInterface = InterfaceFunction changeSpeed : Integer;Function startEngine : Integer;end;carClass = Class(TInterfacedObject,vehiculeInterface)Function changeSpeed : Integer;end;Function carClass.changeSpeed : Integer;beginResult := 5;end;varmyCar : carClass;beginwriteln('Start...');myCar:=carClass.create;;writeln('myCar.changeSpeed = ',myCar.changeSpeed());writeln('End...');end.
When running this code widget, the following error is returned:
Error: No matching implementation for interface method "startEngine:LongInt;" found
This error occurs because the interface declares the startEngine function, but it was not implemented in the carClass class as required.
Code example 3
This example aims to demonstrate how aliases for methods that make up an interface work:
program hello;{$mode objfpc}typevehiculeInterface = InterfaceFunction changeSpeed : Integer;Function startEngine : Integer;end;carClass = Class(TInterfacedObject,vehiculeInterface)Function changeSpeed : Integer;Function vehiculeInterface.startEngine = changeSpeed;end;Function carClass.changeSpeed : Integer;beginResult := 5;end;varmyCar : carClass;beginwriteln('Start...');myCar:=carClass.create;writeln('myCar.changeSpeed = ',myCar.changeSpeed());writeln('End...');end.
The code above is somehow similar to the one elaborated first, Let's go through the lines of codes having differences:
Line 12: According to this declaration, the
startEnginemethod of thevehiculeInterfaceinterface is aliased with thechangeSpeedmethod of thecarClassclass.
As we can see, there is no error returned even though thestartEnginemethod is not defined in thecarClassclass.
Free Resources