Interfaces

Interfaces provide an abstract definition of one or more type members (Methods, Properties or Events) that other types may opt to implement. You can think of them as type contract that a type promises to provide functionality for.

Many types can implement the same interface, regardless of whether thye share a common ancestry in their inheritance hierarchy, and all type implementing the interface can then be interacted with by the same code, without the code having to be aware of the actual concrete types.

Any type opting to implement an interface must provide an implementation for all members of the interface (except for those declared optional, a feature available only on Cocoa objects). All interface members are implied to be public, and no visibility sections are allowed (but for the exception of Private Interface Members discussed below).

By convention, and to provide distinction from concrete types, interface names start with an uppercase I followed by a PascalCased name. But this is not a rule that is compiler-enforced. On the Java, system-provided interfaces do not follow this convention.

An interfaces type is declared using the interface keyword, followed by zero or more member declarations, and closed off with the end keyword. Optionally, one or more base interfaces can be provided in parenthesis behind the interface keyword:

type
  IMyInterface = public interface
    method DoSomething;
  end;

  MyClass = public class(IMyInterface)
  public
    method DoSomething; ///
  end;
  
  var x: IMyInterface;
  x.DoSomething(; // we don't know the actual type of x, onkly that it implements IMyInterface

Interfaces Members are limited to

Like all custom types, interfaces can be nested in other types with nested in syntax.

Default Implementations

Interfaces can optionally choose to provide a default implementation for some of the methods they define. If a default implementation is provided, types implementing the interface may choose not to provide an implementation themselves, and will in that case "inherit" the default implementation.

This is often helpful for interface methods that would be similar form most implementations. Consider the ILogger interface example below. Most concrete implementations would only need to implement the first method to emit the log string to various mediums. The second method is handy to have for callers of the interface, but it would be cumbersome having to re-implement it for each logger.

type
  ILogger = public soft interface
    method Log(aInfo: String);
    method Log(aFormat: String; params aParameters: array of Object);
    begin
      Log(String.Format(aFormat, aParameters));
    end;
  end;

Private Interface Members

As part of default implementations, interfaces can also define private helper members. These members must provide an implementation; they do not become not part of the official interface contract, and are only available from other methods implemented in the same interface. consider:

type
  ILogger = public soft interface
  public
   
    method Log(aInfo: String);
    
    method Log(aFormat: String; params aParameters: array of Object);
    begin
      Log(CustomFormat(aFormat, aParameters));
    end;
    
  private
  
    method CustomFormat(aFormat: String; params aParameters: array of Object);
    begin
      ...
    end;

  end;

Optional Members (Cocoa)

On the Cocoa platform, interface members can be marked as optional with the optional keyword directive. Optional members do not have to (but may) be implemented by classes conforming to the interface. Of course, code calling into such option al members must take care to ensure they are implemented by the concrete instance, at run time – usually by calling the respondsToSelector() method on Cocoa's base Object.

type
  IFoo = public interface
    method One;
    method Two; optional;
  end;

Soft Interfaces

Interfaces can be marked as soft and suitabke for automatic Duck Typing, using the soft modifier keyword. You can read more about how Soft Interfaces, in all Elements languages, here.

type
  ISoftDuck = public soft interface
    method Quack;
  end;

Type Visibility

The visibility of an interface type can be controlled by applying a Visibility Modifier on the declaration. The default visibility is assembly.

Other Modifiers

A number of other Type Modifiers can be applied to classes:

  • soft

See Also