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 they share a common ancestry in their inheritance hierarchy, and all types 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 (with 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 Java, system-provided interfaces do not follow this convention.
An interface 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, only that it implements IMyInterface
Interfaces Members are limited to
- Methods (including Iterators)
- Properties
- Events
- Constants
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 for 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 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): String;
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 optional members must take care to ensure they are implemented by the concrete instance, at runtime – 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 suitable for automatic Duck Typing, using the soft
modifier keyword. You can read more about Soft Interfaces, in all Elements languages, here.
type
ISoftDuck = public soft interface
method Quack;
end;
Combined Interfaces
A Type Alias can combine two or more interfaces into a new interface type that combines both:
type
ICodable = IEncodable and IDecodable;
See the Combined Interfaces topic for more details
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
Only one Type Modifier can be applied to interfaces:
soft
marks the interface as soft (see above)
See Also
Optional
attributeSoftInterface
attribute- Duck Typing
- Type Alias and Combined Interfaces